readIdentifier does not process characters that get truncated

Previously a '.' could be past the truncation limit but still
cause the identifier to be marked as local, violating an
assertion in `sym_AddLocalLabel`.

Fixes #832
This commit is contained in:
Rangi
2021-04-16 21:15:01 -04:00
parent e78a1d5bfd
commit c755fa3469
4 changed files with 36 additions and 18 deletions

View File

@@ -1210,6 +1210,11 @@ static bool startsIdentifier(int c)
return (c <= 'Z' && c >= 'A') || (c <= 'z' && c >= 'a') || c == '.' || c == '_'; return (c <= 'Z' && c >= 'A') || (c <= 'z' && c >= 'a') || c == '.' || c == '_';
} }
static bool continuesIdentifier(int c)
{
return startsIdentifier(c) || (c <= '9' && c >= '0') || c == '#' || c == '@';
}
static int readIdentifier(char firstChar) static int readIdentifier(char firstChar)
{ {
dbgPrint("Reading identifier or keyword\n"); dbgPrint("Reading identifier or keyword\n");
@@ -1217,30 +1222,24 @@ static int readIdentifier(char firstChar)
yylval.tzSym[0] = firstChar; yylval.tzSym[0] = firstChar;
uint16_t nodeID = keywordDict[0].children[dictIndex(firstChar)]; uint16_t nodeID = keywordDict[0].children[dictIndex(firstChar)];
int tokenType = firstChar == '.' ? T_LOCAL_ID : T_ID; int tokenType = firstChar == '.' ? T_LOCAL_ID : T_ID;
size_t i; size_t i = 1;
for (i = 1; ; i++) { /* Continue reading while the char is in the symbol charset */
int c = peek(); for (int c = peek(); continuesIdentifier(c); i++, c = peek()) {
/* If that char isn't in the symbol charset, end */
if ((c > '9' || c < '0')
&& (c > 'Z' || c < 'A')
&& (c > 'z' || c < 'a')
&& c != '#' && c != '.' && c != '@' && c != '_')
break;
shiftChar(); shiftChar();
/* Write the char to the identifier's name */ if (i < sizeof(yylval.tzSym) - 1) {
if (i < sizeof(yylval.tzSym) - 1) /* Write the char to the identifier's name */
yylval.tzSym[i] = c; yylval.tzSym[i] = c;
/* If the char was a dot, mark the identifier as local */ /* If the char was a dot, mark the identifier as local */
if (c == '.') if (c == '.')
tokenType = T_LOCAL_ID; tokenType = T_LOCAL_ID;
/* Attempt to traverse the tree to check for a keyword */ /* Attempt to traverse the tree to check for a keyword */
if (nodeID) /* Do nothing if matching already failed */ if (nodeID) /* Do nothing if matching already failed */
nodeID = keywordDict[nodeID].children[dictIndex(c)]; nodeID = keywordDict[nodeID].children[dictIndex(c)];
}
} }
if (i > sizeof(yylval.tzSym) - 1) { if (i > sizeof(yylval.tzSym) - 1) {

View File

@@ -0,0 +1,11 @@
SECTION "Test", ROM0
MACRO a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
println "truncated :("
ENDM
a012:
a012.local
a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012:
a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012.local

View File

@@ -0,0 +1,7 @@
warning: local-truncated.asm(10): [-Wlong-string]
Symbol name too long, got truncated
ERROR: local-truncated.asm(10):
'a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001' already defined at local-truncated.asm(3)
warning: local-truncated.asm(11): [-Wlong-string]
Symbol name too long, got truncated
error: Assembly aborted (1 error)!

View File

@@ -0,0 +1 @@
truncated :(