From 9e91a1fe89eb3c09dc7b53e4d7c5ecea5006b649 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 18 Nov 2025 15:40:02 +0000 Subject: [PATCH] Modify the "%realloc" and "%free" commands in Lemon so that the functions they specify take an extra parameter at the end, the %extra_context pointer. This allows the implementation to distinguish between OOM errors and failures to increase the stack size because of the stack size limit. FossilOrigin-Name: 9862c945d9a8531f9bef123aee9ed1fd3f64542250a57beb3a150227bc3c1a12 --- doc/lemon.html | 22 +++++++++++++--------- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/parse.y | 16 +++++++++++++--- tool/lempar.c | 8 +++++--- 5 files changed, 40 insertions(+), 24 deletions(-) diff --git a/doc/lemon.html b/doc/lemon.html index 0f5de0913b..a994b396b7 100644 --- a/doc/lemon.html +++ b/doc/lemon.html @@ -1208,20 +1208,24 @@ The wildcard token is only matched if there are no alternatives.
%stack_size_limit directivesThe %realloc and %free directives defines function -that allocate and free heap memory. The signatures of these functions -should be the same as the realloc() and free() functions from the standard -C library. - -
If both of these functions are defined -then these functions are used to allocate and free -memory for supplemental parser stack space, if the initial -parse stack space is exceeded. The initial parser stack size +that allocate and free heap memory. The signatures and semantics of +these functions are similar to the realloc() and free() functions from +the standard C library, except that these functions take an extra +parameter at the end that is determined by %extra_context. If +%extra_context is not defined, then the extra argument is 0. The +extra parameter provides the capability to do better error reporting +in the event of a memory allocation error, and/or to use an alternative +private application heap. + +
If both of these functions are defined then they are used to +allocate and free memory for supplemental parser stack space, if +the initial parse stack space is exceeded. The initial parser stack size is specified by either %stack_size or the -DYYSTACKDEPTH compile-time flag.
The %stack_size_limit directive defines a function that returns the maximum allowed parser stack size. If this diretive does not exist, -no size limit is enforced. The function takes a single argument which +no size limit is enforced. This function takes a single argument which is the %extra_context value or "0" if %extra_context is not defined. The function should return an integer that is the maximum number of parser stack entries. If more stack space diff --git a/manifest b/manifest index 04b3c2b801..e7c1491bbe 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Lower\sthe\sdefault\sstack\ssize\sfor\sthe\sparse\sto\s50. -D 2025-11-18T15:20:22.796 +C Modify\sthe\s"%realloc"\sand\s"%free"\scommands\sin\sLemon\sso\sthat\sthe\sfunctions\nthey\sspecify\stake\san\sextra\sparameter\sat\sthe\send,\sthe\s%extra_context\spointer.\nThis\sallows\sthe\simplementation\sto\sdistinguish\sbetween\sOOM\serrors\sand\nfailures\sto\sincrease\sthe\sstack\ssize\sbecause\sof\sthe\sstack\ssize\slimit. +D 2025-11-18T15:40:02.793 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -60,7 +60,7 @@ F doc/compile-for-unix.md c9dce1ddd4bf0d25efccc5c63eb047e78c01ce06a6ff29c73e0a8a F doc/compile-for-windows.md f9e74d74da88f384edd5809f825035e071608f00f7f39c0e448df7b3982f979c F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347bb123ce1ea4f F doc/jsonb.md acd77fc3a709f51242655ad7803510c886aa8304202fa9cf2abc5f5c4e9d7ae5 -F doc/lemon.html b4a2ce0ad754bf8ea46fe146bfe6134388748a0a1bcc8292847a52a75307ad4d +F doc/lemon.html 2085fda0a90a94fe92159a79dccc5c30d5a2313524887a31659cd66162f17233 F doc/pager-invariants.txt 83aa3a4724b2d7970cc3f3461f0295c46d4fc19a835a5781cbb35cb52feb0577 F doc/tcl-extension-testing.md b88861804fc1eaf83249f8e206334189b61e150c360e1b80d0dcf91af82354f5 F doc/testrunner.md 5ee928637e03f136a25fef852c5ed975932e31927bd9b05a574424ae18c31019 @@ -720,7 +720,7 @@ F src/os_win.c a89b501fc195085c7d6c9eec7f5bd782625e94bb2a96b000f4d009703df1083f F src/os_win.h 4c247cdb6d407c75186c94a1e84d5a22cbae4adcec93fcae8d2bc1f956fd1f19 F src/pager.c a81461de271ac4886ad75b7ca2cca8157a48635820c4646cd2714acdc2c17e5f F src/pager.h 6137149346e6c8a3ddc1eeb40aee46381e9bc8b0fcc6dda8a1efde993c2275b8 -F src/parse.y afa49045cdd54131a7b2a0a7ab0401111d1ed6972ac323081e2dfe09e4de1bac +F src/parse.y 4266eeb7dd9a03195e7701e9f2272fac2d950f2c1e629da49aa62b272611eac3 F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5 F src/pcache1.c 131ca0daf4e66b4608d2945ae76d6ed90de3f60539afbd5ef9ec65667a5f2fcd @@ -2102,7 +2102,7 @@ F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/index_usage.c f62a0c701b2c7ff2f3e21d206f093c123f222dbf07136a10ffd1ca15a5c706c5 F tool/lemon.c 4150f2020d453cfa46b6fa45542e59b923ad7eab063fb4ca20777995622cab0b -F tool/lempar.c 25aea31b33bbd15f0f7324c796e160c602f2a1d4e3f6f87d6d4fb25d77eaf54a +F tool/lempar.c b57e1780bf8098dd4a9a5bba537f994276ea825a420f6165153e5894dc2dfb07 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c 63412f9790e5e8538fbde0b4f6db154aaaf80f7a10a01e3c94d14b773a8dd5a6 F tool/logest.c c34e5944318415de513d29a6098df247a9618c96d83c38d4abd88641fe46e669 @@ -2166,8 +2166,8 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8f0b07f36159225c476f756f8f9b35c75783bc8bed43b578f4d1055fa800ecc9 -R c68f53fdd732bf66e96ffccfbfad06fd +P 41fe19ab054acda912bc32dd6f9c6412416ab1af6cf55515e96c89fb55b46424 +R eaedc8a6fb66bf638a3308ee531542c6 U drh -Z bf286ce506e13b7f5702e955703a4050 +Z cd45861cdfb2c55973d9d3bae678a719 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e1ebb8b18f..fbcb312fee 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -41fe19ab054acda912bc32dd6f9c6412416ab1af6cf55515e96c89fb55b46424 +9862c945d9a8531f9bef123aee9ed1fd3f64542250a57beb3a150227bc3c1a12 diff --git a/src/parse.y b/src/parse.y index 67635f42af..afafb35b04 100644 --- a/src/parse.y +++ b/src/parse.y @@ -25,7 +25,7 @@ %stack_size 50 // Initial stack size %stack_size_limit parserStackSizeLimit // Function returning max stack size %realloc parserStackRealloc // realloc() for the stack -%free sqlite3_free // free() for the stack +%free parserStackFree // free() for the stack // All token codes are small integers with #defines that begin with "TK_" %token_prefix TK_ @@ -585,8 +585,18 @@ cmd ::= select(X). { ** sqlite3_realloc() that includes a call to sqlite3FaultSim() to facilitate ** testing. */ - static void *parserStackRealloc(void *pOld, sqlite3_uint64 newSize){ - return sqlite3FaultSim(700) ? 0 : sqlite3_realloc(pOld, newSize); + static void *parserStackRealloc( + void *pOld, /* Prior allocation */ + sqlite3_uint64 newSize, /* Requested new alloation size */ + Parse *pParse /* Parsing context */ + ){ + void *p = sqlite3FaultSim(700) ? 0 : sqlite3_realloc(pOld, newSize); + if( p==0 ) sqlite3OomFault(pParse->db); + return p; + } + static void parserStackFree(void *pOld, Parse *pParse){ + (void)pParse; + sqlite3_free(pOld); } /* Return an integer that is the maximum allowed stack size */ diff --git a/tool/lempar.c b/tool/lempar.c index c99f2a8f1c..7b654e6503 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -312,11 +312,11 @@ static int yyGrowStack(yyParser *p){ #endif idx = (int)(p->yytos - p->yystack); if( p->yystack==p->yystk0 ){ - pNew = YYREALLOC(0, newSize*sizeof(pNew[0])); + pNew = YYREALLOC(0, newSize*sizeof(pNew[0]), ParseCTX(p)); if( pNew==0 ) return 1; memcpy(pNew, p->yystack, oldSize*sizeof(pNew[0])); }else{ - pNew = YYREALLOC(p->yystack, newSize*sizeof(pNew[0])); + pNew = YYREALLOC(p->yystack, newSize*sizeof(pNew[0]), ParseCTX(p)); if( pNew==0 ) return 1; } p->yystack = pNew; @@ -468,7 +468,9 @@ void ParseFinalize(void *p){ } #if YYGROWABLESTACK - if( pParser->yystack!=pParser->yystk0 ) YYFREE(pParser->yystack); + if( pParser->yystack!=pParser->yystk0 ){ + YYFREE(pParser->yystack, ParseCTX(pParser)); + } #endif } -- 2.47.3