The problem occurs when \@ is accessed outside the definition of a
macro and is not between "" or {}, or when it is used in an argument of
a macro call, i.e. when the access is processed by PutUniqueArg().
PutUniqueArg(), puts back the string value of \@ to the lexer's buffer
(to substitute \@ by the unique label string).
When \@ is not defined, sym_FindMacroArg(-1) returns NULL, which
yyunputstr() doesn't expect and crashes.
Solution:
Generate an error when \@ is not defined.
Regression test:
SECTION "HOME", HOME
ld a,\@
Will segfault.
On the fixed version, it will return an error as \@ is not available.
- separated the lexer into multiple functions so it is more readable
- fixed issue with long label names in macro arguments
- added error checking code to prevent buffer overflows
Symbols are created when using a label in the wild, even if they aren't defined. Solely using a symbol as an argument to BANK() skips this, so the symbol is never created.
This evaluates the argument instead of trying to find a symbol. This way, symbols that don't exist are created when passed into BANK().
On Linux, valgrind complains about the overflow like this:
Pass 1...
==20054== Invalid read of size 1
==20054== at 0x406CDA: yylex (lexer.c:396)
==20054== by 0x40207C: yyparse (asmy.c:2921)
==20054== by 0x4086AF: main (main.c:351)
==20054== Address 0x503a102 is 0 bytes after a block of size 23,538 alloc'd
==20054== at 0x402994D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20054== by 0x406411: yy_create_buffer (lexer.c:147)
==20054== by 0x404FE3: fstk_RunInclude (fstack.c:243)
==20054== by 0x4025F5: yyparse (asmy.y:744)
==20054== by 0x4086AF: main (main.c:351)
==20054==
This is a bit of a crude fix which simply exits the hashing loop when
we reach the end of the string. We should probably do some kind of
length calculation on the buffer instead.
Signed-off-by: Vegard Nossum <vegard.nossum@gmail.com>