{"action":"created","issue":{"url":"https://api.github.com/repos/cc65/cc65/issues/728","repository_url":"https://api.github.com/repos/cc65/cc65","labels_url":"https://api.github.com/repos/cc65/cc65/issues/728/labels{/name}","comments_url":"https://api.github.com/repos/cc65/cc65/issues/728/comments","events_url":"https://api.github.com/repos/cc65/cc65/issues/728/events","html_url":"https://github.com/cc65/cc65/issues/728","id":352639819,"node_id":"MDU6SXNzdWUzNTI2Mzk4MTk=","number":728,"title":"Unterminated string literal causes compiler to SIGSEGV","user":{"login":"ppelleti","id":1080008,"node_id":"MDQ6VXNlcjEwODAwMDg=","avatar_url":"https://avatars2.githubusercontent.com/u/1080008?v=4","gravatar_id":"","url":"https://api.github.com/users/ppelleti","html_url":"https://github.com/ppelleti","followers_url":"https://api.github.com/users/ppelleti/followers","following_url":"https://api.github.com/users/ppelleti/following{/other_user}","gists_url":"https://api.github.com/users/ppelleti/gists{/gist_id}","starred_url":"https://api.github.com/users/ppelleti/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ppelleti/subscriptions","organizations_url":"https://api.github.com/users/ppelleti/orgs","repos_url":"https://api.github.com/users/ppelleti/repos","events_url":"https://api.github.com/users/ppelleti/events{/privacy}","received_events_url":"https://api.github.com/users/ppelleti/received_events","type":"User","site_admin":false},"labels":[{"id":32846633,"node_id":"MDU6TGFiZWwzMjg0NjYzMw==","url":"https://api.github.com/repos/cc65/cc65/labels/bug","name":"bug","color":"fc2929","default":true}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-08-21T17:33:35Z","updated_at":"2018-10-03T08:12:19Z","closed_at":null,"author_association":"CONTRIBUTOR","body":"This is a continuation of #724, because I think there was an underlying bug that was triggered by the illegal escape sequence.  This bug reproduces the same SIGSEGV, but without needing an illegal escape sequence.  (Because the illegal escape sequence bug is now fixed, so that it does not result in an unterminated string literal.)\r\n\r\nI can still cause a SIGSEGV in the same place, just by introducing an unterminated string literal manually:\r\n```c\r\n/* cc65 -t sim6502 this-causes-a-segfault.c */\r\n\r\nenum foo {\r\n    J65_DONE,\r\n    J65_STRING,\r\n};\r\n\r\ntypedef struct {\r\n    enum foo ev;\r\n    const char *str;\r\n} event_check;\r\n\r\nstatic const event_check test20[] = {\r\n    { J65_DONE, \" },\r\n    { J65_STRING, \"\" },\r\n};\r\n```\r\nWhen I run it under LLDB, I get:\r\n```\r\nWhiteAndNerdy:scratch ppelleti$ lldb -- cc65 -t sim6502 this-causes-a-segfault.c\r\n(lldb) target create \"cc65\"\r\nCurrent executable set to 'cc65' (x86_64).\r\n(lldb) settings set -- target.run-args  \"-t\" \"sim6502\" \"this-causes-a-segfault.c\"\r\n(lldb) r\r\nProcess 59463 launched: '/Users/ppelleti/.local/bin/cc65' (x86_64)\r\nthis-causes-a-segfault.c(14): Error: Unexpected newline\r\nthis-causes-a-segfault.c(15): Error: `}' expected\r\nthis-causes-a-segfault.c(15): Error: `}' expected\r\nthis-causes-a-segfault.c(15): Error: `;' expected\r\nthis-causes-a-segfault.c(15): Error: Identifier expected\r\nthis-causes-a-segfault.c(15): Warning: Implicit `int' is an obsolete feature\r\nthis-causes-a-segfault.c(15): Error: `;' expected\r\nthis-causes-a-segfault.c(15): Warning: Implicit `int' is an obsolete feature\r\nthis-causes-a-segfault.c(15): Warning: public declaration follows static declaration of `J65_STRING'.\r\nProcess 59463 stopped\r\n* thread #1: tid = 0x2b2057f, 0x00007fff8e60fd13 libsystem_platform.dylib`_platform_strcmp + 19, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x1)\r\n    frame #0: 0x00007fff8e60fd13 libsystem_platform.dylib`_platform_strcmp + 19\r\nlibsystem_platform.dylib`_platform_strcmp + 19:\r\n-> 0x7fff8e60fd13:  movzbq (%rdi), %rax\r\n   0x7fff8e60fd17:  movzbq (%rsi), %r8\r\n   0x7fff8e60fd1b:  incq   %rdi\r\n   0x7fff8e60fd1e:  incq   %rsi\r\n(lldb) bt\r\n* thread #1: tid = 0x2b2057f, 0x00007fff8e60fd13 libsystem_platform.dylib`_platform_strcmp + 19, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x1)\r\n  * frame #0: 0x00007fff8e60fd13 libsystem_platform.dylib`_platform_strcmp + 19\r\n    frame #1: 0x00000001000104d5 cc65`Compile [inlined] Parse + 728 at compile.c:258\r\n    frame #2: 0x00000001000101fd cc65`Compile(FileName=<unavailable>) + 589 at compile.c:403\r\n    frame #3: 0x0000000100032250 cc65`main(argc=4, argv=0x0000000100103b60) + 1504 at main.c:1055\r\n    frame #4: 0x00007fff8d86f5fd libdyld.dylib`start + 1\r\n(lldb) up\r\nframe #1: 0x00000001000104d5 cc65`Compile [inlined] Parse + 728 at compile.c:258\r\n   255 \t                        */\r\n   256 \t                        const char* bssName = GetSegName (SEG_BSS);\r\n   257 \t\r\n-> 258 \t                        if (Entry->V.BssName && strcmp (Entry->V.BssName, bssName) != 0) {\r\n   259 \t                            Error (\"Global variable `%s' already was defined in the `%s' segment.\",\r\n   260 \t                                   Entry->Name, Entry->V.BssName);\r\n   261 \t                        }\r\n(lldb) print Entry->V.BssName\r\n(const char *) $0 = 0x0000000000000001 \"\"\r\n(lldb) \r\n```\r\nSo, it is still trying to use the enumeration value of `J65_STRING` (1) as `Entry->V.BssName`.\r\n\r\nThis is on Mac OS X 10.9.5, using a cc65 built from the current head, 31461aaf0204aaaf9807008c2bd1a7fde6097f3b."},"comment":{"url":"https://api.github.com/repos/cc65/cc65/issues/comments/426549121","html_url":"https://github.com/cc65/cc65/issues/728#issuecomment-426549121","issue_url":"https://api.github.com/repos/cc65/cc65/issues/728","id":426549121,"node_id":"MDEyOklzc3VlQ29tbWVudDQyNjU0OTEyMQ==","user":{"login":"laubzega","id":5245003,"node_id":"MDQ6VXNlcjUyNDUwMDM=","avatar_url":"https://avatars0.githubusercontent.com/u/5245003?v=4","gravatar_id":"","url":"https://api.github.com/users/laubzega","html_url":"https://github.com/laubzega","followers_url":"https://api.github.com/users/laubzega/followers","following_url":"https://api.github.com/users/laubzega/following{/other_user}","gists_url":"https://api.github.com/users/laubzega/gists{/gist_id}","starred_url":"https://api.github.com/users/laubzega/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/laubzega/subscriptions","organizations_url":"https://api.github.com/users/laubzega/orgs","repos_url":"https://api.github.com/users/laubzega/repos","events_url":"https://api.github.com/users/laubzega/events{/privacy}","received_events_url":"https://api.github.com/users/laubzega/received_events","type":"User","site_admin":false},"created_at":"2018-10-03T08:12:19Z","updated_at":"2018-10-03T08:12:19Z","author_association":"CONTRIBUTOR","body":"First, it's not really about an unterminated string. This code\r\n\r\n```\r\nstatic const event_check test20[] = {\r\n     { J65_DONE, \"\"\r\n     { J65_STRING, \"\" },\r\n};\r\n```\r\ncauses the same crash and same debug output. The unterminated string simply \"eats\" the comman and the closing bracket and this is what makes the compiler lethally confused. It stops parsing the array initialization, stumbles a few times, and finally figures that `J65_STRING ` in the next line is a global symbol that needs to be added to the symbol table. There however it finds `J65_STRING ` enum which was registered a few lines above, so decides to work with it instead. That proves fatal, as symbol of type `SC_ENUM ` uses different fields of union `SymEntry.V`, offering enum's value of 1 as a pointer. Boom!\r\n\r\nIn general, while in this case it is easy to avoid the crash, the insistence of `symtab.c/AddGlobalSym()` on returning an existing `SymEntry ` even when it realizes that something is wrong seems to be asking for trouble.  I would not be surprised if other crash bugs could be produced by abusing it.\r\n\r\nEither `AddGlobalSym()` should abort the compilation at a first hint of mismatches between what's being added and what's already present in the symbol table, or much more strict validation needs to be done whenever `SymEntry ` is accessed, just to make sure that the fields reached for indeed exist.\r\n\r\nI don't know cc65 well enough to judge which approach is more sensible."}}
{"actor":{"display_login":"laubzega"}}