aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/lemon/CMakeLists.txt63
-rw-r--r--tools/lemon/README15
-rwxr-xr-xtools/lemon/apply-patches.sh10
-rw-r--r--tools/lemon/cppmagic.h13
-rw-r--r--tools/lemon/lemon.c98
-rw-r--r--tools/lemon/lemonflex-head.inc33
-rw-r--r--tools/lemon/lemonflex-tail.inc77
-rw-r--r--tools/lemon/lempar.c122
-rw-r--r--tools/lemon/patches/01-lempar-wireshark-warnings.patch49
-rw-r--r--tools/lemon/patches/02-lemon-fix-dead-store.patch13
-rw-r--r--tools/lemon/patches/03-lemon-null-deref-fp.patch34
-rw-r--r--tools/lemon/patches/04-lemon-struct-copy-memleak-fp.patch45
-rw-r--r--tools/lemon/patches/05-lemon-memleak-alloc-failure.patch12
-rw-r--r--tools/lemon/patches/08-lemon-stp-memleak-fp.patch20
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;