From: drh <> Date: Tue, 24 Mar 2026 19:26:05 +0000 (+0000) Subject: Prevent overly long JSON paths from using too much stack space. X-Git-Tag: major-release~51 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=53197b79403497886c40ec658d50385d8ccc01c2;p=thirdparty%2Fsqlite.git Prevent overly long JSON paths from using too much stack space. FossilOrigin-Name: 82a0794814bbc095235f8158a4129a5d83f6af1b0c27cb56449ea32feb44faf5 --- diff --git a/manifest b/manifest index 12b5022b4d..cc620d23ee 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Limit\sJSONB\srecursion\sdepth\sin\sthe\sjson_patch()\sfunction. -D 2026-03-24T12:39:05.703 +C Prevent\soverly\slong\sJSON\spaths\sfrom\susing\stoo\smuch\sstack\sspace. +D 2026-03-24T19:26:05.509 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -694,7 +694,7 @@ F src/hash.h 46b92795a95bfefb210f52f0c316e9d7cdbcdd7e7fcfb0d8be796d3a5767cddf F src/hwtime.h 21c2cf1f736e7b97502c3674d0c386db3f06870d6f10d0cf8174e2a4b8cb726e F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c dfd311b0ac2d4f6359e62013db67799757f4d2cc56cca5c10f4888acfbbfa3fd -F src/json.c 3d790a2822cf3938d808dd4c82713e640f2fc410504b0f853dc32b8fa585bad4 +F src/json.c 5027b856cd9b621dc9ba66b211e21a440ccdc63cefdefb44c51e7d3ac550d1a4 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 187929338d21f43cbdea359a3c1ec61294f39b7f9032e824c1dbb79f9994c838 F src/main.c 31a13302193fbd51279c7e69cdfa0320d0de7629f9151e0964c1d320e8bdd7a4 @@ -2195,8 +2195,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c -P 82036fafa175e798fd32b3dc4ad043fc2bbe2bb2af17781f12dcb4d23a233865 -R cfe70b6eb98b5198569bd46361e5c403 +P f8659b700c0088abe19ce65fec032c1005a1f750566488f4578256d41558770c +R 758e0af8a0882e7e9923c695c5403a23 U drh -Z 24e4693854a4d68b165699d3ce0f66fc +Z 1af8ca46b9aa6ac26d04c5ed95b2b6cf # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5e31359323..81366cb24e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f8659b700c0088abe19ce65fec032c1005a1f750566488f4578256d41558770c +82a0794814bbc095235f8158a4129a5d83f6af1b0c27cb56449ea32feb44faf5 diff --git a/src/json.c b/src/json.c index 73912a4e1f..f3d5aadcf7 100644 --- a/src/json.c +++ b/src/json.c @@ -2898,7 +2898,8 @@ static int jsonLabelCompare( #define JSON_LOOKUP_ERROR 0xffffffff #define JSON_LOOKUP_NOTFOUND 0xfffffffe #define JSON_LOOKUP_NOTARRAY 0xfffffffd -#define JSON_LOOKUP_PATHERROR 0xfffffffc +#define JSON_LOOKUP_TOODEEP 0xfffffffc +#define JSON_LOOKUP_PATHERROR 0xfffffffb #define JSON_LOOKUP_ISERROR(x) ((x)>=JSON_LOOKUP_PATHERROR) /* Forward declaration */ @@ -2945,7 +2946,12 @@ static u32 jsonCreateEditSubstructure( pIns->eEdit = pParse->eEdit; pIns->nIns = pParse->nIns; pIns->aIns = pParse->aIns; + pIns->iDepth = pParse->iDepth+1; + if( pIns->iDepth >= JSON_MAX_DEPTH ){ + return JSON_LOOKUP_TOODEEP; + } rc = jsonLookupStep(pIns, 0, zTail, 0); + pParse->iDepth--; pParse->oom |= pIns->oom; } return rc; /* Error code only */ @@ -3051,7 +3057,11 @@ static u32 jsonLookupStep( n = jsonbPayloadSize(pParse, v, &sz); if( n==0 || v+n+sz>iEnd ) return JSON_LOOKUP_ERROR; assert( j>0 ); + if( ++pParse->iDepth >= JSON_MAX_DEPTH ){ + return JSON_LOOKUP_TOODEEP; + } rc = jsonLookupStep(pParse, v, &zPath[i], j); + pParse->iDepth--; if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot); return rc; } @@ -3137,7 +3147,11 @@ static u32 jsonLookupStep( iEnd = j+sz; while( jiDepth >= JSON_MAX_DEPTH ){ + return JSON_LOOKUP_TOODEEP; + } rc = jsonLookupStep(pParse, j, &zPath[i+1], 0); + pParse->iDepth--; if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot); return rc; } @@ -3473,9 +3487,10 @@ static int jsonFunctionArgToBlob( ** ** The specifics of the error are determined by the rc argument. ** -** rc error -** ----------------- ---------------- +** rc error +** ----------------- ---------------------- ** JSON_LOOKUP_ARRAY "not an array" +** JSON_LOOKUP_TOODEEP "JSON nested too deep" ** JSON_LOOKUP_ERROR "malformed JSON" ** otherwise... "bad JSON path" ** @@ -3492,6 +3507,8 @@ static char *jsonBadPathError( zMsg = sqlite3_mprintf("not an array element: %Q", zPath); }else if( rc==(int)JSON_LOOKUP_ERROR ){ zMsg = sqlite3_mprintf("malformed JSON"); + }else if( rc==(int)JSON_LOOKUP_TOODEEP ){ + zMsg = sqlite3_mprintf("JSON path too deep"); }else{ zMsg = sqlite3_mprintf("bad JSON path: %Q", zPath); } @@ -3554,6 +3571,7 @@ static void jsonInsertIntoBlob( p->nIns = ax.nBlob; p->aIns = ax.aBlob; p->delta = 0; + p->iDepth = 0; rc = jsonLookupStep(p, 0, zPath+1, 0); } jsonParseReset(&ax);