We bumped the # of tokens in the TOKENSTREAM structure from 32 to 64,
but also added some logic to the macro invocation code to check if we
break the limits and thus don't crash. Will 64 be enough? My crystal
ball is cloudy ATM... :-P
// Parse out the arguments and set them up correctly
TOKEN * p = imacro->argument[nargs].token;
int stringNum = 0;
// Parse out the arguments and set them up correctly
TOKEN * p = imacro->argument[nargs].token;
int stringNum = 0;
while (*tok != EOL)
{
if (*tok == ACONST)
{
while (*tok != EOL)
{
if (*tok == ACONST)
{
+ // Sanity checking (it's numTokens + 1 because we need an EOL
+ // if we successfully parse this argument)
+ if ((numTokens + 3) >= TS_MAXTOKENS)
+ return error("Too many tokens in argument #%d in MACRO invocation", nargs + 1);
+
for(int i=0; i<3; i++)
*p++ = *tok++;
for(int i=0; i<3; i++)
*p++ = *tok++;
}
else if (*tok == CONST) // Constants are 64-bits
{
}
else if (*tok == CONST) // Constants are 64-bits
{
+ // Sanity checking (it's numTokens + 1 because we need an EOL
+ // if we successfully parse this argument)
+ if ((numTokens + 3) >= TS_MAXTOKENS)
+ return error("Too many tokens in argument #%d in MACRO invocation", nargs + 1);
+
*p++ = *tok++; // Token
uint64_t *p64 = (uint64_t *)p;
uint64_t *tok64 = (uint64_t *)tok;
*p64++ = *tok64++;
tok = (TOKEN *)tok64;
p = (uint32_t *)p64;
*p++ = *tok++; // Token
uint64_t *p64 = (uint64_t *)p;
uint64_t *tok64 = (uint64_t *)tok;
*p64++ = *tok64++;
tok = (TOKEN *)tok64;
p = (uint32_t *)p64;
}
else if ((*tok == STRING) || (*tok == SYMBOL))
{
}
else if ((*tok == STRING) || (*tok == SYMBOL))
{
+ // Sanity checking (it's numTokens + 1 because we need an EOL
+ // if we successfully parse this argument)
+ if (stringNum >= TS_MAXSTRINGS)
+ return error("Too many strings in argument #%d in MACRO invocation", nargs + 1);
+
+ if ((numTokens + 2) >= TS_MAXTOKENS)
+ return error("Too many tokens in argument #%d in MACRO invocation", nargs + 1);
+
*p++ = *tok++;
imacro->argument[nargs].string[stringNum] = strdup(string[*tok++]);
*p++ = stringNum++;
*p++ = *tok++;
imacro->argument[nargs].string[stringNum] = strdup(string[*tok++]);
*p++ = stringNum++;
}
else if (*tok == ',')
{
}
else if (*tok == ',')
{
+ // Sanity checking
+ if ((nargs + 1) >= TS_MAXARGS)
+ return error("Too many arguments in MACRO invocation");
+
// Comma delimiter was found, so set up for next argument
*p++ = EOL;
tok++;
stringNum = 0;
// Comma delimiter was found, so set up for next argument
*p++ = EOL;
tok++;
stringNum = 0;
nargs++;
p = imacro->argument[nargs].token;
}
else
{
nargs++;
p = imacro->argument[nargs].token;
}
else
{
+ // Sanity checking (it's numTokens + 1 because we need an EOL
+ // if we successfully parse this argument)
+ if ((numTokens + 1) >= TS_MAXTOKENS)
+ return error("Too many tokens in argument #%d in MACRO invocation", nargs + 1);
+
return 0x04;
else if (strcmp(scratchbuf, "RELEASE") == 0)
return 0x08;
return 0x04;
else if (strcmp(scratchbuf, "RELEASE") == 0)
return 0x08;
char * GetNextMacroLine(void)
{
IMACRO * imacro = cur_inobj->inobj.imacro;
char * GetNextMacroLine(void)
{
IMACRO * imacro = cur_inobj->inobj.imacro;
-// LONG * strp = imacro->im_nextln;
LLIST * strp = imacro->im_nextln;
if (strp == NULL) // End-of-macro
LLIST * strp = imacro->im_nextln;
if (strp == NULL) // End-of-macro
#define SRC_IREPT 2 // Input source is IREPT
// Macros
#define SRC_IREPT 2 // Input source is IREPT
// Macros
-#define INOBJ struct _inobj
-#define IUNION union _iunion
-#define IFILE struct _incldfile
-#define IMACRO struct _imacro
-#define IREPT struct _irept
-#define IFENT struct _ifent
+#define INOBJ struct _inobj
+#define IUNION union _iunion
+#define IFILE struct _incldfile
+#define TOKENSTREAM struct _tokenstream
+#define IMACRO struct _imacro
+#define IREPT struct _irept
+#define IFENT struct _ifent
// Tunable definitions
#define LNSIZ 1024 // Maximum size of a line of text
// Tunable definitions
#define LNSIZ 1024 // Maximum size of a line of text
char ifbuf[LNBUFSIZ]; // Line buffer
};
char ifbuf[LNBUFSIZ]; // Line buffer
};
-#define TOKENSTREAM struct _tokenstream
+// Consts for maximums in TOKENSTREAM
+#define TS_MAXTOKENS 64 // 32 ought to be enough for anybody (including XiA!)
+#define TS_MAXSTRINGS 32 // same for attached strings
+#define TS_MAXARGS 20 // Assume no more than 20 arguments in an invocation
+
- TOKEN token[32]; // 32 ought to be enough for anybody (including XiA!)
- char * string[32]; // same for attached strings
+ TOKEN token[TS_MAXTOKENS];
+ char * string[TS_MAXSTRINGS];
};
// Information about a macro invocation
};
// Information about a macro invocation
LONG im_olduniq; // Old value of 'macuniq'
SYM * im_macro; // Pointer to macro we're in
char im_lnbuf[LNSIZ]; // Line buffer
LONG im_olduniq; // Old value of 'macuniq'
SYM * im_macro; // Pointer to macro we're in
char im_lnbuf[LNSIZ]; // Line buffer
- TOKENSTREAM argument[20]; // Assume no more than 20 arguments in an invocation
+ TOKENSTREAM argument[TS_MAXARGS];
};
// Information about a .rept invocation
};
// Information about a .rept invocation
#define MAJOR 2 // Major version number
#define MINOR 0 // Minor version number
#define MAJOR 2 // Major version number
#define MINOR 0 // Minor version number
-#define PATCH 21 // Patch release number
+#define PATCH 22 // Patch release number