diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/lemon/CMakeLists.txt | 63 | ||||
-rw-r--r-- | tools/lemon/README | 15 | ||||
-rwxr-xr-x | tools/lemon/apply-patches.sh | 10 | ||||
-rw-r--r-- | tools/lemon/cppmagic.h | 13 | ||||
-rw-r--r-- | tools/lemon/lemon.c | 98 | ||||
-rw-r--r-- | tools/lemon/lemonflex-head.inc | 33 | ||||
-rw-r--r-- | tools/lemon/lemonflex-tail.inc | 77 | ||||
-rw-r--r-- | tools/lemon/lempar.c | 122 | ||||
-rw-r--r-- | tools/lemon/patches/01-lempar-wireshark-warnings.patch | 49 | ||||
-rw-r--r-- | tools/lemon/patches/02-lemon-fix-dead-store.patch | 13 | ||||
-rw-r--r-- | tools/lemon/patches/03-lemon-null-deref-fp.patch | 34 | ||||
-rw-r--r-- | tools/lemon/patches/04-lemon-struct-copy-memleak-fp.patch | 45 | ||||
-rw-r--r-- | tools/lemon/patches/05-lemon-memleak-alloc-failure.patch | 12 | ||||
-rw-r--r-- | tools/lemon/patches/08-lemon-stp-memleak-fp.patch | 20 |
14 files changed, 136 insertions, 468 deletions
diff --git a/tools/lemon/CMakeLists.txt b/tools/lemon/CMakeLists.txt index 8742aa9fc9..529eeae11d 100644 --- a/tools/lemon/CMakeLists.txt +++ b/tools/lemon/CMakeLists.txt @@ -14,58 +14,23 @@ if(DEFINED LEMON_C_COMPILER) set(CMAKE_C_FLAGS "") endif() -# To keep lemon.c as close to upstream as possible, deliberately ignore -# some stylistic issues. -set(lemon_cflags) +# To keep lemon.c as close to upstream as possible disable all warnings if(CMAKE_C_COMPILER_ID MATCHES "MSVC") - # Normal MSVC has no warnings, but VS Code Analysis finds a bunch - # (when ENABLE_CODE_ANALYSIS is set). - set(lemon_cflags - /wd6001 # Using uninitialized memory '*zBuf'. - /wd6011 # Dereferencing NULL pointer 'cp'. - /wd6308 # realloc may return NULL and leak original memory. - /wd6385 # Buffer overrun (read) in Parse, related to 'cp' - /wd6386 # Buffer overrun (write) in Parse, related to 'filebuf' - /wd6387 # strlen(argv[0]) could receive a NULL pointer. - /wd28182 # Dereferencing NULL pointer. 'ap2' contains the same NULL value as 'ap' did. - /wd28183 # passing 0 (from realloc) to memcpy - /wd28199 # Using possibly uninitialized memory - ) + target_compile_options(lemon PRIVATE /w) else() - set(lemon_cflags_test - # GCC 8.2.1 is not smart enough to recognize "Fall thru ..." - -Wimplicit-fallthrough - -Wsign-compare - -Wunused-parameter - -Wshorten-64-to-32 - # From WIRESHARK_C_ONLY_FLAGS - -Wc++-compat - -Wold-style-definition - -Wstrict-prototypes - ) - if(ENABLE_EXTRA_COMPILER_WARNINGS) - list(APPEND lemon_cflags_test - -Wpedantic - -Wstrict-overflow - -Wcast-qual - -Wredundant-decls - -Wmissing-prototypes - -Wmissing-declarations - -Wcast-align - ) - endif() - foreach(THIS_FLAG IN LISTS lemon_cflags_test) - string(MAKE_C_IDENTIFIER "C${THIS_FLAG}_VALID" _flag_var) - check_c_compiler_flag(${THIS_FLAG} ${_flag_var}) - if(${_flag_var}) - # Look for -Wfoo flags above in case it is cached, but - # actually disable the warning here with -Wno-foo. - string(REPLACE "-W" "-Wno-" THIS_FLAG "${THIS_FLAG}") - list(APPEND lemon_cflags ${THIS_FLAG}) - endif() - endforeach() + target_compile_options(lemon PRIVATE -w) +endif() +if(CMAKE_C_COMPILER_ID MATCHES "Clang") + # Disable static analysis for lemon source code. These issues don't + # affect Wireshark at runtime. + target_compile_options(lemon PRIVATE -Xclang -analyzer-disable-all-checks) +endif() +if(DEFINED NO_SANITIZE_CFLAGS) + target_compile_options(lemon PRIVATE ${NO_SANITIZE_CFLAGS}) +endif() +if(DEFINED NO_SANITIZE_LDFLAGS) + target_link_options(lemon PRIVATE ${NO_SANITIZE_LDFLAGS}) endif() -target_compile_options(lemon PRIVATE ${lemon_cflags}) # # Editor modelines - https://www.wireshark.org/tools/modelines.html diff --git a/tools/lemon/README b/tools/lemon/README index ab9c008b63..59ed343182 100644 --- a/tools/lemon/README +++ b/tools/lemon/README @@ -7,11 +7,11 @@ Git mirror of the upstream Fossil repository: https://github.com/mackyle/sqlite The lempar.c and lemon.c are taken from sqlite and are modified as little as possible to make it easier to synchronize changes. Last updated at: - commit 273ee151217b04c640c1af148e36c518678c89fa - Author: mistachkin <mistachkin@noemail.net> - Date: Mon Sep 21 20:18:44 2020 +0000 + commit a913f942cf6b32b85de6428fd542b39458df2a88 + Author: D. Richard Hipp <drh@hwaci.com> + Date: Wed Dec 28 14:03:47 2022 +0000 - Fix harmless compiler warning seen with MSVC. + Version 3.40.1 To check for changes (adjust "previous commit" accordingly): @@ -26,6 +26,13 @@ To create a Wireshark version (steps 1-3) and validate the result (steps 4-5): 4. Check for CSA warnings: clang-check -analyze lemon.c -- 5. Build and run lemon: ninja epan/dfilter/grammar.c +To keep the lemon source as pristine as possible from upstream all warnings +when building lemon itself are disabled. Only patch the lemon source code as +a last resort. + +Warnings for lemon generated code are few in practice with -Wall -Wextra. These +are preferably selectively disabled in the Wireshark build. + The patches to lemon to silence compiler warnings and static analysis reports (for edge cases that cannot occur) are not proposed upstream because that process is difficult. From <https://www.sqlite.org/copyright.html>: diff --git a/tools/lemon/apply-patches.sh b/tools/lemon/apply-patches.sh index 5ffb47c372..e445c87a59 100755 --- a/tools/lemon/apply-patches.sh +++ b/tools/lemon/apply-patches.sh @@ -6,9 +6,11 @@ sed -e 's/ \+$//' -i lemon.c lempar.c # Other patches -for i in patches/*.patch; do - echo "Applying $i" - patch --silent -p1 -i "$i" -done +if [ -d "patches" ]; then + for i in patches/*.patch; do + echo "Applying $i" + patch --silent -p1 -i "$i" + done +fi echo DONE diff --git a/tools/lemon/cppmagic.h b/tools/lemon/cppmagic.h deleted file mode 100644 index 74599ef093..0000000000 --- a/tools/lemon/cppmagic.h +++ /dev/null @@ -1,13 +0,0 @@ -/** @file */ -/**************************************** CPP definitions ***************/ - -/* CPP magic: Concatenate two strings or macros that resolve to strings. - * Use CONCAT(), not _CONCAT() */ -#define _CONCAT(a,b) a ## b -#define CONCAT(a,b) _CONCAT(a,b) - -/* CPP magic: Surround a string or a macro that resolves to a string with - * double quotes. */ -#define _STRINGIFY(a) # a -#define STRINGIFY(a) _STRINGIFY(a) - diff --git a/tools/lemon/lemon.c b/tools/lemon/lemon.c index 8f990824a9..869ac58049 100644 --- a/tools/lemon/lemon.c +++ b/tools/lemon/lemon.c @@ -48,7 +48,7 @@ extern int access(const char *path, int mode); #define MAXRHS 1000 #endif -extern void memory_error(void); +extern void memory_error(); static int showPrecedenceConflict = 0; static char *msort(char*,char**,int(*)(const char*,const char*)); @@ -401,7 +401,7 @@ struct lemon { struct symbol *errsym; /* The error symbol */ struct symbol *wildcard; /* Token that matches anything */ char *name; /* Name of the generated parser */ - char *arg; /* Declaration of the 3th argument to parser */ + char *arg; /* Declaration of the 3rd argument to parser */ char *ctx; /* Declaration of 2nd argument to constructor */ char *tokentype; /* Type of terminal symbols in the parser stack */ char *vartype; /* The default type of non-terminal symbols */ @@ -430,6 +430,7 @@ struct lemon { }; #define MemoryCheck(X) if((X)==0){ \ + extern void memory_error(); \ memory_error(); \ } @@ -694,13 +695,11 @@ int acttab_insert(acttab *p, int makeItSafe){ fprintf(stderr,"malloc failed\n"); exit(1); } - assert(oldAlloc < p->nActionAlloc); /* hint for CSA */ for(i=oldAlloc; i<p->nActionAlloc; i++){ p->aAction[i].lookahead = -1; p->aAction[i].action = -1; } } - assert(p->aAction); /* Hint for CSA (for p->aAction[i] below) */ /* Scan the existing action table looking for an offset that is a ** duplicate of the current transaction set. Fall out of the loop @@ -918,8 +917,11 @@ void FindStates(struct lemon *lemp) lemp->errorcnt++; sp = lemp->startRule->lhs; } - }else{ + }else if( lemp->startRule ){ sp = lemp->startRule->lhs; + }else{ + ErrorMsg(lemp->filename,0,"Internal error - no start rule\n"); + exit(1); } /* Make sure the start symbol doesn't occur on the right-hand side of @@ -994,13 +996,7 @@ PRIVATE struct state *getstate(struct lemon *lemp) stp->cfp = cfp; /* Remember the configuration closure */ stp->statenum = lemp->nstate++; /* Every state gets a sequence number */ stp->ap = 0; /* No actions, yet. */ -#ifndef NDEBUG - int ret = -#endif State_insert(stp,stp->bp); /* Add to the state table */ -#ifndef NDEBUG - assert(ret == 1); /* CSA hint: stp did not leak, it has escaped. */ -#endif buildshifts(lemp,stp); /* Recursively compute successor states */ } return stp; @@ -1034,7 +1030,7 @@ PRIVATE void buildshifts(struct lemon *lemp, struct state *stp) struct symbol *bsp; /* Symbol following the dot in configuration "bcfp" */ struct state *newstp; /* A pointer to a successor state */ - /* Each configuration becomes complete after it contibutes to a successor + /* Each configuration becomes complete after it contributes to a successor ** state. Initially, all configurations are incomplete */ for(cfp=stp->cfp; cfp; cfp=cfp->next) cfp->status = INCOMPLETE; @@ -1090,8 +1086,7 @@ void FindLinks(struct lemon *lemp) ** which the link is attached. */ for(i=0; i<lemp->nstate; i++){ stp = lemp->sorted[i]; - assert(stp); /* Hint for CSA */ - for(cfp=stp->cfp; cfp; cfp=cfp->next){ + for(cfp=stp?stp->cfp:0; cfp; cfp=cfp->next){ cfp->stp = stp; } } @@ -1100,7 +1095,7 @@ void FindLinks(struct lemon *lemp) ** links are used in the follow-set computation. */ for(i=0; i<lemp->nstate; i++){ stp = lemp->sorted[i]; - for(cfp=stp->cfp; cfp; cfp=cfp->next){ + for(cfp=stp?stp->cfp:0; cfp; cfp=cfp->next){ for(plp=cfp->bplp; plp; plp=plp->next){ other = plp->cfp; Plink_add(&other->fplp,cfp); @@ -1123,6 +1118,7 @@ void FindFollowSets(struct lemon *lemp) int change; for(i=0; i<lemp->nstate; i++){ + assert( lemp->sorted[i]!=0 ); for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){ cfp->status = INCOMPLETE; } @@ -1131,6 +1127,7 @@ void FindFollowSets(struct lemon *lemp) do{ progress = 0; for(i=0; i<lemp->nstate; i++){ + assert( lemp->sorted[i]!=0 ); for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){ if( cfp->status==COMPLETE ) continue; for(plp=cfp->fplp; plp; plp=plp->next){ @@ -1180,7 +1177,14 @@ void FindActions(struct lemon *lemp) /* Add the accepting token */ if( lemp->start ){ sp = Symbol_find(lemp->start); - if( sp==0 ) sp = lemp->startRule->lhs; + if( sp==0 ){ + if( lemp->startRule==0 ){ + fprintf(stderr, "internal error on source line %d: no start rule\n", + __LINE__); + exit(1); + } + sp = lemp->startRule->lhs; + } }else{ sp = lemp->startRule->lhs; } @@ -1307,21 +1311,7 @@ static struct config **basisend = 0; /* End of list of basis configs */ /* Return a pointer to a new configuration */ PRIVATE struct config *newconfig(void){ - struct config *newcfg; - if( freelist==0 ){ - int i; - int amt = 3; - freelist = (struct config *)calloc( amt, sizeof(struct config) ); - if( freelist==0 ){ - fprintf(stderr,"Unable to allocate memory for a new configuration."); - exit(1); - } - for(i=0; i<amt-1; i++) freelist[i].next = &freelist[i+1]; - freelist[amt-1].next = 0; - } - newcfg = freelist; - freelist = freelist->next; - return newcfg; + return (struct config*)calloc(1, sizeof(struct config)); } /* The configuration "old" is no longer used */ @@ -1703,7 +1693,6 @@ int main(int argc, char **argv){ /* Parse the input file */ Parse(&lem); if( lem.printPreprocessed || lem.errorcnt ) exit(lem.errorcnt); - assert(lem.rule); /* Hint for CSA (no errors => rule found). */ if( lem.nrule==0 ){ fprintf(stderr,"Empty grammar.\n"); exit(1); @@ -1896,7 +1885,7 @@ static char *merge( ** ** Return Value: ** A pointer to the head of a sorted list containing the elements -** orginally in list. +** originally in list. ** ** Side effects: ** The "next" pointers for elements in list are changed. @@ -1941,8 +1930,12 @@ static FILE *errstream; static void errline(int n, int k, FILE *err) { int spcnt, i; - if( g_argv[0] ) fprintf(err,"%s",g_argv[0]); - spcnt = lemonStrlen(g_argv[0]) + 1; + if( g_argv[0] ){ + fprintf(err,"%s",g_argv[0]); + spcnt = lemonStrlen(g_argv[0]) + 1; + }else{ + spcnt = 0; + } for(i=1; i<n && g_argv[i]; i++){ fprintf(err," %s",g_argv[i]); spcnt += lemonStrlen(g_argv[i])+1; @@ -2717,7 +2710,7 @@ static void parseonetoken(struct pstate *psp) ** in order to control their assigned integer number. The number for ** each token is assigned when it is first seen. So by including ** - ** %token ONE TWO THREE + ** %token ONE TWO THREE. ** ** early in the grammar file, that assigns small consecutive values ** to each of the tokens ONE TWO and THREE. @@ -3022,6 +3015,7 @@ void Parse(struct lemon *gp) } if( c=='/' && cp[1]=='*' ){ /* Skip C style comments */ cp+=2; + if( (*cp)=='/' ) cp++; while( (c= *cp)!=0 && (c!='/' || cp[-1]!='*') ){ if( c=='\n' ) lineno++; cp++; @@ -3522,7 +3516,7 @@ void ReportOutput(struct lemon *lemp) } /* Search for the file "name" which is in the same directory as -** the exacutable */ +** the executable */ PRIVATE char *pathsearch(char *argv0, char *name, int modemask) { const char *pathlist; @@ -3547,7 +3541,6 @@ PRIVATE char *pathsearch(char *argv0, char *name, int modemask) if( pathlist==0 ) pathlist = ".:/bin:/usr/bin"; pathbuf = (char *) malloc( lemonStrlen(pathlist) + 1 ); path = (char *)malloc( lemonStrlen(pathlist)+lemonStrlen(name)+2 ); - MemoryCheck(pathbuf); MemoryCheck(path); /* Fail on allocation failure. */ if( (pathbuf != 0) && (path!=0) ){ pathbufptr = pathbuf; lemon_strcpy(pathbuf, pathlist); @@ -3581,7 +3574,9 @@ PRIVATE int compute_action(struct lemon *lemp, struct action *ap) /* Since a SHIFT is inherient after a prior REDUCE, convert any ** SHIFTREDUCE action with a nonterminal on the LHS into a simple ** REDUCE action: */ - if( ap->sp->index>=lemp->nterminal ){ + if( ap->sp->index>=lemp->nterminal + && (lemp->errsym==0 || ap->sp->index!=lemp->errsym->index) + ){ act = lemp->minReduce + ap->x.rp->iRule; }else{ act = lemp->minShiftReduce + ap->x.rp->iRule; @@ -3878,7 +3873,7 @@ PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){ lhsdirect = 1; }else if( rp->rhsalias[0]==0 ){ /* The left-most RHS symbol has no value. LHS direct is ok. But - ** we have to call the distructor on the RHS symbol first. */ + ** we have to call the destructor on the RHS symbol first. */ lhsdirect = 1; if( has_destructor(rp->rhs[0],lemp) ){ append_str(0,0,0,0); @@ -4296,7 +4291,6 @@ void ReportTable( int sqlFlag /* Generate the *.sql file too */ ){ FILE *out, *in, *sql; - char line[LINESIZE]; int lineno; struct state *stp; struct action *ap; @@ -4771,7 +4765,6 @@ void ReportTable( /* Generate a table containing the symbolic name of every symbol */ for(i=0; i<lemp->nsymbol; i++){ - lemon_sprintf(line,"\"%s\",",lemp->symbols[i]->name); fprintf(out," /* %4d */ \"%s\",\n",i, lemp->symbols[i]->name); lineno++; } tplt_xfer(lemp->name,in,out,&lineno); @@ -4859,7 +4852,7 @@ void ReportTable( ** yyRuleInfoNRhs[]. ** ** Note: This code depends on the fact that rules are number - ** sequentually beginning with 0. + ** sequentially beginning with 0. */ for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){ fprintf(out," %4d, /* (%d) ", rp->lhs->index, i); @@ -5347,8 +5340,9 @@ int Strsafe_insert(const char *data) newnp->from = &(array.ht[h]); array.ht[h] = newnp; } - free(x1a->tbl); - memcpy(x1a, &array, sizeof(array)); /* *x1a = array; */ + /* free(x1a->tbl); // This program was originally for 16-bit machines. + ** Don't worry about freeing memory on modern platforms. */ + *x1a = array; } /* Insert the new data */ h = ph & (x1a->size-1); @@ -5515,8 +5509,10 @@ int Symbol_insert(struct symbol *data, const char *key) newnp->from = &(array.ht[h]); array.ht[h] = newnp; } - free(x2a->tbl); - memcpy(x2a, &array, sizeof(array)); /* *x2a = array; */ + /* free(x2a->tbl); // This program was originally written for 16-bit + ** machines. Don't worry about freeing this trivial amount of memory + ** on modern platforms. Just leak it. */ + *x2a = array; } /* Insert the new data */ h = ph & (x2a->size-1); @@ -5713,7 +5709,7 @@ int State_insert(struct state *data, struct config *key) array.ht[h] = newnp; } free(x3a->tbl); - memcpy(x3a, &array, sizeof(array)); /* *x3a = array; */ + *x3a = array; } /* Insert the new data */ h = ph & (x3a->size-1); @@ -5851,8 +5847,10 @@ int Configtable_insert(struct config *data) newnp->from = &(array.ht[h]); array.ht[h] = newnp; } - free(x4a->tbl); - memcpy(x4a, &array, sizeof(array)); /* *x4a = array; */ + /* free(x4a->tbl); // This code was originall written for 16-bit machines. + ** on modern machines, don't worry about freeing this trival amount of + ** memory. */ + *x4a = array; } /* Insert the new data */ h = ph & (x4a->size-1); diff --git a/tools/lemon/lemonflex-head.inc b/tools/lemon/lemonflex-head.inc deleted file mode 100644 index e6350caae3..0000000000 --- a/tools/lemon/lemonflex-head.inc +++ /dev/null @@ -1,33 +0,0 @@ - -/* This file is #include'd at the top of a Lex/Flex scanner -for use with the Lemon parser. You must have #define'd: - -LVAL name of lval variable -LVAL_TYPE type of lval variable -LVAL_INIT_VAL Initial value of lval variable - -*/ - -/* Flex has a few routines which help us get the scanner to read - * from a string rather than from a file. POSIX lex only provides - * for reading from a file; any method of reading from a string - * is inherently non-portable. Besides reading from a string, - * we have to worry about resetting the scanner after a bad - * parse; this too is non-portable. Combine the reset with - * a string input, and you have major non-portability. I'll provide - * the routines for flex here. If you really want to modify the - * scanner and use a non-flex lex implementation, you may - * add more ifdef's below. - */ - - -/* If we don't need yyunput, use this macro to get it out of the - * generated C file, avoiding a compiler warning about its lack of use */ -#define YY_NO_UNPUT 1 - - -/* Yup, I'm using a non-standard type for lval, unlike usual lex/yacc implementations. - * I can do so because I'm *not* using yacc, I'm using Lemon, where I have - * more control of the interaction between scanner and parser. */ -LVAL_TYPE LVAL = LVAL_INIT_VAL; - diff --git a/tools/lemon/lemonflex-tail.inc b/tools/lemon/lemonflex-tail.inc deleted file mode 100644 index 5a63fdd3f6..0000000000 --- a/tools/lemon/lemonflex-tail.inc +++ /dev/null @@ -1,77 +0,0 @@ - -/* This file is #include'd at the bottom of a Lex/Flex scanner -for use with the Lemon parser. You must have #define'd: - -MODNAME module name for creating function names: - -Prototypes: -*/ -void CONCAT(MODNAME,_scanner_text(char *text)); -void CONCAT(MODNAME,_scanner_file(FILE *fh)); -void CONCAT(MODNAME,_scanner_cleanup(void)); -#ifndef YY_SKIP_YYWRAP -int CONCAT(MODNAME,_wrap(void)); -#endif - -#include <cppmagic.h> - -#define TEXT_FUNC CONCAT(MODNAME,_scanner_text) -#define FILE_FUNC CONCAT(MODNAME,_scanner_file) -#define CLEANUP_FUNC CONCAT(MODNAME,_scanner_cleanup) -#ifndef YY_SKIP_YYWRAP -#define WRAP_FUNC CONCAT(MODNAME,_wrap) -#endif - -/* flex 2.5.31 no longer #defines these as yy_* if used with -P. */ -#ifndef yy_scan_string -#define yy_scan_string CONCAT(FLEX_YY_PREFIX, _scan_string) -#endif - -#ifndef yy_create_buffer -#define yy_create_buffer CONCAT(FLEX_YY_PREFIX, _create_buffer) -#endif - -#ifndef yy_switch_to_buffer -#define yy_switch_to_buffer CONCAT(FLEX_YY_PREFIX, _switch_to_buffer) -#endif - -#ifndef yy_delete_buffer -#define yy_delete_buffer CONCAT(FLEX_YY_PREFIX, _delete_buffer) -#endif - -/* Resets scanner and assigns the char* argument - * as the text to scan - */ -void -TEXT_FUNC (char *text) -{ - yy_scan_string(text); -} - -void -FILE_FUNC (FILE* fh) -{ - YY_BUFFER_STATE new_buffer; - - new_buffer = yy_create_buffer(fh, YY_BUF_SIZE); - yy_switch_to_buffer(new_buffer); -} - -void -CLEANUP_FUNC (void) -{ - BEGIN(INITIAL); - yy_delete_buffer(YY_CURRENT_BUFFER); -} - -#ifndef YY_SKIP_YYWRAP -/* Flex has an option '%option noyywrap' so that I don't have to - * provide this yywrap function, but in order to maintain portability, - * I'll just use this yywrap() function if that option wasn't used. - */ -int -WRAP_FUNC (void) -{ - return 1; /* stop at EOF, instead of looking for next file */ -} -#endif diff --git a/tools/lemon/lempar.c b/tools/lemon/lempar.c index 6651281573..fcb72b8afe 100644 --- a/tools/lemon/lempar.c +++ b/tools/lemon/lempar.c @@ -223,9 +223,9 @@ struct yyParser { }; typedef struct yyParser yyParser; +#include <assert.h> #ifndef NDEBUG #include <stdio.h> -#include <assert.h> static FILE *yyTraceFILE = 0; static char *yyTracePrompt = 0; #endif /* NDEBUG */ @@ -317,7 +317,7 @@ static int yyGrowStack(yyParser *p){ /* Initialize a new parser that has already been allocated. */ -static void ParseInit(void *yypRawParser ParseCTX_PDECL){ +void ParseInit(void *yypRawParser ParseCTX_PDECL){ yyParser *yypParser = (yyParser*)yypRawParser; ParseCTX_STORE #ifdef YYTRACKMAXSTACKDEPTH @@ -424,7 +424,7 @@ static void yy_pop_parser_stack(yyParser *pParser){ /* ** Clear all secondary memory allocations from the parser */ -static void ParseFinalize(void *p){ +void ParseFinalize(void *p){ yyParser *pParser = (yyParser*)p; while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser); #if YYSTACKDEPTH<=0 @@ -718,55 +718,6 @@ static YYACTIONTYPE yy_reduce( (void)yyLookahead; (void)yyLookaheadToken; yymsp = yypParser->yytos; - assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ); -#ifndef NDEBUG - if( yyTraceFILE ){ - yysize = yyRuleInfoNRhs[yyruleno]; - if( yysize ){ - fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", - yyTracePrompt, - yyruleno, yyRuleName[yyruleno], - yyruleno<YYNRULE_WITH_ACTION ? "" : " without external action", - yymsp[yysize].stateno); - }else{ - fprintf(yyTraceFILE, "%sReduce %d [%s]%s.\n", - yyTracePrompt, yyruleno, yyRuleName[yyruleno], - yyruleno<YYNRULE_WITH_ACTION ? "" : " without external action"); - } - } -#endif /* NDEBUG */ - - /* Check that the stack is large enough to grow by a single entry - ** if the RHS of the rule is empty. This ensures that there is room - ** enough on the stack to push the LHS value */ - if( yyRuleInfoNRhs[yyruleno]==0 ){ -#ifdef YYTRACKMAXSTACKDEPTH - if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){ - yypParser->yyhwm++; - assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack)); - } -#endif -#if YYSTACKDEPTH>0 - if( yypParser->yytos>=yypParser->yystackEnd ){ - yyStackOverflow(yypParser); - /* The call to yyStackOverflow() above pops the stack until it is - ** empty, causing the main parser loop to exit. So the return value - ** is never used and does not matter. */ - return 0; - } -#else - if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ - if( yyGrowStack(yypParser) ){ - yyStackOverflow(yypParser); - /* The call to yyStackOverflow() above pops the stack until it is - ** empty, causing the main parser loop to exit. So the return value - ** is never used and does not matter. */ - return 0; - } - yymsp = yypParser->yytos; - } -#endif - } switch( yyruleno ){ /* Beginning here are the reduction cases. A typical example @@ -831,7 +782,7 @@ static void yy_parse_failed( */ static void yy_syntax_error( yyParser *yypParser, /* The parser */ - int yymajor _U_, /* The major type of the error token */ + int yymajor, /* The major type of the error token */ ParseTOKENTYPE yyminor /* The minor type of the error token */ ){ ParseARG_FETCH @@ -925,12 +876,56 @@ void Parse( } #endif - do{ + while(1){ /* Exit by "break" */ + assert( yypParser->yytos>=yypParser->yystack ); assert( yyact==yypParser->yytos->stateno ); yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact); if( yyact >= YY_MIN_REDUCE ){ - yyact = yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor, - yyminor ParseCTX_PARAM); + unsigned int yyruleno = yyact - YY_MIN_REDUCE; /* Reduce by this rule */ +#ifndef NDEBUG + assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ); + if( yyTraceFILE ){ + int yysize = yyRuleInfoNRhs[yyruleno]; + if( yysize ){ + fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", + yyTracePrompt, + yyruleno, yyRuleName[yyruleno], + yyruleno<YYNRULE_WITH_ACTION ? "" : " without external action", + yypParser->yytos[yysize].stateno); + }else{ + fprintf(yyTraceFILE, "%sReduce %d [%s]%s.\n", + yyTracePrompt, yyruleno, yyRuleName[yyruleno], + yyruleno<YYNRULE_WITH_ACTION ? "" : " without external action"); + } + } +#endif /* NDEBUG */ + + /* Check that the stack is large enough to grow by a single entry + ** if the RHS of the rule is empty. This ensures that there is room + ** enough on the stack to push the LHS value */ + if( yyRuleInfoNRhs[yyruleno]==0 ){ +#ifdef YYTRACKMAXSTACKDEPTH + if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){ + yypParser->yyhwm++; + assert( yypParser->yyhwm == + (int)(yypParser->yytos - yypParser->yystack)); + } +#endif +#if YYSTACKDEPTH>0 + if( yypParser->yytos>=yypParser->yystackEnd ){ + yyStackOverflow(yypParser); + break; + } +#else + if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ + if( yyGrowStack(yypParser) ){ + yyStackOverflow(yypParser); + break; + } + } +#endif + } + yyact = yy_reduce(yypParser,yyruleno,yymajor,yyminor ParseCTX_PARAM); }else if( yyact <= YY_MAX_SHIFTREDUCE ){ yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor); #ifndef YYNOERRORRECOVERY @@ -986,14 +981,13 @@ void Parse( yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion); yymajor = YYNOCODE; }else{ - while( yypParser->yytos >= yypParser->yystack - && (yyact = yy_find_reduce_action( - yypParser->yytos->stateno, - YYERRORSYMBOL)) > YY_MAX_SHIFTREDUCE - ){ + while( yypParser->yytos > yypParser->yystack ){ + yyact = yy_find_reduce_action(yypParser->yytos->stateno, + YYERRORSYMBOL); + if( yyact<=YY_MAX_SHIFTREDUCE ) break; yy_pop_parser_stack(yypParser); } - if( yypParser->yytos < yypParser->yystack || yymajor==0 ){ + if( yypParser->yytos <= yypParser->yystack || yymajor==0 ){ yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); yy_parse_failed(yypParser); #ifndef YYNOERRORRECOVERY @@ -1043,7 +1037,7 @@ void Parse( break; #endif } - }while( yypParser->yytos>yypParser->yystack ); + } #ifndef NDEBUG if( yyTraceFILE ){ yyStackEntry *i; @@ -1059,7 +1053,6 @@ void Parse( return; } -#if 0 /* ** Return the fallback token corresponding to canonical token iToken, or ** 0 if iToken has no fallback. @@ -1073,4 +1066,3 @@ int ParseFallback(int iToken){ return 0; #endif } -#endif diff --git a/tools/lemon/patches/01-lempar-wireshark-warnings.patch b/tools/lemon/patches/01-lempar-wireshark-warnings.patch deleted file mode 100644 index 38636542c7..0000000000 --- a/tools/lemon/patches/01-lempar-wireshark-warnings.patch +++ /dev/null @@ -1,49 +0,0 @@ -Make ParseInit and ParseFinalize static to fix -Wmissing-prototypes in -dtd_grammar.c. Hide ParseFallback to fix -Wunused-function since this feature -is not used by Wireshark. - -Mark yymajor as _U_ since none of the lemon grammar files seem to use it in -their %syntax_error directive, this fixes -Wunused-parameter -SPDX-License-Identifier: CC0-1.0 ---- a/lempar.c -+++ b/lempar.c -@@ -317,7 +317,7 @@ static int yyGrowStack(yyParser *p){ - - /* Initialize a new parser that has already been allocated. - */ --void ParseInit(void *yypRawParser ParseCTX_PDECL){ -+static void ParseInit(void *yypRawParser ParseCTX_PDECL){ - yyParser *yypParser = (yyParser*)yypRawParser; - ParseCTX_STORE - #ifdef YYTRACKMAXSTACKDEPTH -@@ -424,7 +424,7 @@ static void yy_pop_parser_stack(yyParser *pParser){ - /* - ** Clear all secondary memory allocations from the parser - */ --void ParseFinalize(void *p){ -+static void ParseFinalize(void *p){ - yyParser *pParser = (yyParser*)p; - while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser); - #if YYSTACKDEPTH<=0 -@@ -831,7 +831,7 @@ static void yy_parse_failed( - */ - static void yy_syntax_error( - yyParser *yypParser, /* The parser */ -- int yymajor, /* The major type of the error token */ -+ int yymajor _U_, /* The major type of the error token */ - ParseTOKENTYPE yyminor /* The minor type of the error token */ - ){ - ParseARG_FETCH -@@ -1059,6 +1059,7 @@ void Parse( - return; - } - -+#if 0 - /* - ** Return the fallback token corresponding to canonical token iToken, or - ** 0 if iToken has no fallback. -@@ -1072,3 +1073,4 @@ int ParseFallback(int iToken){ - return 0; - #endif - } -+#endif diff --git a/tools/lemon/patches/02-lemon-fix-dead-store.patch b/tools/lemon/patches/02-lemon-fix-dead-store.patch deleted file mode 100644 index 9ca304f9a2..0000000000 --- a/tools/lemon/patches/02-lemon-fix-dead-store.patch +++ /dev/null @@ -1,13 +0,0 @@ -Avoid dead store warning, the same assignment happens later in this function. -SPDX-License-Identifier: CC0-1.0 ---- a/lemon.c -+++ b/lemon.c -@@ -4090,7 +4101,7 @@ void print_stack_union( - int *plineno, /* Pointer to the line number */ - int mhflag /* True if generating makeheaders output */ - ){ -- int lineno = *plineno; /* The line number of the output */ -+ int lineno; /* The line number of the output */ - char **types; /* A hash table of datatypes */ - int arraysize; /* Size of the "types" array */ - int maxdtlength; /* Maximum length of any ".datatype" field. */ diff --git a/tools/lemon/patches/03-lemon-null-deref-fp.patch b/tools/lemon/patches/03-lemon-null-deref-fp.patch deleted file mode 100644 index 351486f549..0000000000 --- a/tools/lemon/patches/03-lemon-null-deref-fp.patch +++ /dev/null @@ -1,34 +0,0 @@ -Assertions to avoid false null-pointer dereferences. -SPDX-License-Identifier: CC0-1.0 ---- a/lemon.c -+++ b/lemon.c -@@ -695,11 +695,13 @@ int acttab_insert(acttab *p, int makeItSafe){ - fprintf(stderr,"malloc failed\n"); - exit(1); - } -+ assert(oldAlloc < p->nActionAlloc); /* hint for CSA */ - for(i=oldAlloc; i<p->nActionAlloc; i++){ - p->aAction[i].lookahead = -1; - p->aAction[i].action = -1; - } - } -+ assert(p->aAction); /* Hint for CSA (for p->aAction[i] below) */ - - /* Scan the existing action table looking for an offset that is a - ** duplicate of the current transaction set. Fall out of the loop -@@ -1083,6 +1091,7 @@ void FindLinks(struct lemon *lemp) - ** which the link is attached. */ - for(i=0; i<lemp->nstate; i++){ - stp = lemp->sorted[i]; -+ assert(stp); /* Hint for CSA */ - for(cfp=stp->cfp; cfp; cfp=cfp->next){ - cfp->stp = stp; - } -@@ -1695,6 +1704,7 @@ int main(int argc, char **argv) - /* Parse the input file */ - Parse(&lem); - if( lem.printPreprocessed || lem.errorcnt ) exit(lem.errorcnt); -+ assert(lem.rule); /* Hint for CSA (no errors => rule found). */ - if( lem.nrule==0 ){ - fprintf(stderr,"Empty grammar.\n"); - exit(1); diff --git a/tools/lemon/patches/04-lemon-struct-copy-memleak-fp.patch b/tools/lemon/patches/04-lemon-struct-copy-memleak-fp.patch deleted file mode 100644 index 1e46494025..0000000000 --- a/tools/lemon/patches/04-lemon-struct-copy-memleak-fp.patch +++ /dev/null @@ -1,45 +0,0 @@ -Workaround for CSA limitation, it currently does not correctly handle structure -assignment. Escaping the pointer via function call is a workaround to hide the -false positive (use-after-free). Change done with: -sed -e 's#\*\(x[1-4]a\) = array;$#memcpy(\1, \&array, sizeof(array)); /* & */#' - -Link: https://bugs.llvm.org/show_bug.cgi?id=39356 -SPDX-License-Identifier: CC0-1.0 ---- a/lemon.c -+++ b/lemon.c -@@ -5338,7 +5349,7 @@ int Strsafe_insert(const char *data) - array.ht[h] = newnp; - } - free(x1a->tbl); -- *x1a = array; -+ memcpy(x1a, &array, sizeof(array)); /* *x1a = array; */ - } - /* Insert the new data */ - h = ph & (x1a->size-1); -@@ -5506,7 +5517,7 @@ int Symbol_insert(struct symbol *data, const char *key) - array.ht[h] = newnp; - } - free(x2a->tbl); -- *x2a = array; -+ memcpy(x2a, &array, sizeof(array)); /* *x2a = array; */ - } - /* Insert the new data */ - h = ph & (x2a->size-1); -@@ -5703,7 +5714,7 @@ int State_insert(struct state *data, struct config *key) - array.ht[h] = newnp; - } - free(x3a->tbl); -- *x3a = array; -+ memcpy(x3a, &array, sizeof(array)); /* *x3a = array; */ - } - /* Insert the new data */ - h = ph & (x3a->size-1); -@@ -5842,7 +5853,7 @@ int Configtable_insert(struct config *data) - array.ht[h] = newnp; - } - free(x4a->tbl); -- *x4a = array; -+ memcpy(x4a, &array, sizeof(array)); /* *x4a = array; */ - } - /* Insert the new data */ - h = ph & (x4a->size-1); diff --git a/tools/lemon/patches/05-lemon-memleak-alloc-failure.patch b/tools/lemon/patches/05-lemon-memleak-alloc-failure.patch deleted file mode 100644 index 9aca3e08e8..0000000000 --- a/tools/lemon/patches/05-lemon-memleak-alloc-failure.patch +++ /dev/null @@ -1,12 +0,0 @@ -Avoid leaking pathbuf when path==0 by marking allocation failures as fatal. -SPDX-License-Identifier: CC0-1.0 ---- a/lemon.c -+++ b/lemon.c -@@ -3538,6 +3548,7 @@ PRIVATE char *pathsearch(char *argv0, char *name, int modemask) - if( pathlist==0 ) pathlist = ".:/bin:/usr/bin"; - pathbuf = (char *) malloc( lemonStrlen(pathlist) + 1 ); - path = (char *)malloc( lemonStrlen(pathlist)+lemonStrlen(name)+2 ); -+ MemoryCheck(pathbuf); MemoryCheck(path); /* Fail on allocation failure. */ - if( (pathbuf != 0) && (path!=0) ){ - pathbufptr = pathbuf; - lemon_strcpy(pathbuf, pathlist); diff --git a/tools/lemon/patches/08-lemon-stp-memleak-fp.patch b/tools/lemon/patches/08-lemon-stp-memleak-fp.patch deleted file mode 100644 index 6b9bc9a11c..0000000000 --- a/tools/lemon/patches/08-lemon-stp-memleak-fp.patch +++ /dev/null @@ -1,20 +0,0 @@ -CSA thought that stp would leak if State_insert returns early: when x3a is NULL -(memory allocation failure) or when the state existed before (cannot happen for -the initial state). So annotate it as such. -SPDX-License-Identifier: CC0-1.0 ---- a/lemon.c -+++ b/lemon.c -@@ -993,7 +995,13 @@ PRIVATE struct state *getstate(struct lemon *lemp) - stp->cfp = cfp; /* Remember the configuration closure */ - stp->statenum = lemp->nstate++; /* Every state gets a sequence number */ - stp->ap = 0; /* No actions, yet. */ -+#ifndef NDEBUG -+ int ret = -+#endif - State_insert(stp,stp->bp); /* Add to the state table */ -+#ifndef NDEBUG -+ assert(ret == 1); /* CSA hint: stp did not leak, it has escaped. */ -+#endif - buildshifts(lemp,stp); /* Recursively compute successor states */ - } - return stp; |