From: Shamus Hammons Date: Tue, 29 Sep 2020 02:41:40 +0000 (-0500) Subject: Fix for bug #51. Now at v2.0.22. X-Git-Tag: v2.1.0~3 X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=commitdiff_plain;h=ba8121d8647b88276977b37a425a9b5dc631731e Fix for bug #51. Now at v2.0.22. 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 --- diff --git a/macro.c b/macro.c index 22bd0d9..17378dc 100644 --- a/macro.c +++ b/macro.c @@ -406,41 +406,75 @@ int InvokeMacro(SYM * mac, WORD siz) // Parse out the arguments and set them up correctly TOKEN * p = imacro->argument[nargs].token; int stringNum = 0; + int numTokens = 0; 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++; + + numTokens += 3; } 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; + numTokens += 3; } 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++; + numTokens += 2; } 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; + numTokens = 0; 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); + *p++ = *tok++; + numTokens++; } } diff --git a/op.c b/op.c index 836f4de..3833bfb 100644 --- a/op.c +++ b/op.c @@ -89,6 +89,7 @@ static inline uint64_t CheckFlags(char * s) return 0x04; else if (strcmp(scratchbuf, "RELEASE") == 0) return 0x08; + return 0; } diff --git a/token.c b/token.c index 9299e3f..fa5af09 100644 --- a/token.c +++ b/token.c @@ -673,7 +673,6 @@ overflow: 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 diff --git a/token.h b/token.h index 95adf01..251a503 100644 --- a/token.h +++ b/token.h @@ -17,12 +17,13 @@ #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 @@ -126,10 +127,14 @@ IFILE { 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 + TOKENSTREAM { - 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 @@ -141,7 +146,7 @@ IMACRO { 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 diff --git a/version.h b/version.h index 5764ad5..6b5d5ef 100644 --- a/version.h +++ b/version.h @@ -15,7 +15,7 @@ #define MAJOR 2 // Major version number #define MINOR 0 // Minor version number -#define PATCH 21 // Patch release number +#define PATCH 22 // Patch release number #endif // __VERSION_H__