]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Limit JSONB recursion depth in the json_patch() function.
authordrh <>
Tue, 24 Mar 2026 12:39:05 +0000 (12:39 +0000)
committerdrh <>
Tue, 24 Mar 2026 12:39:05 +0000 (12:39 +0000)
FossilOrigin-Name: f8659b700c0088abe19ce65fec032c1005a1f750566488f4578256d41558770c

manifest
manifest.uuid
src/json.c

index c240c1a97d276bb4cd592acd9abf5814ded2cc06..12b5022b4d0ca70b8acbfee2670ea35453d3bcfe 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Improved\serror\smessages\sfor\sJSONB\snested\stoo\sdeep.
-D 2026-03-24T11:54:55.461
+C Limit\sJSONB\srecursion\sdepth\sin\sthe\sjson_patch()\sfunction.
+D 2026-03-24T12:39:05.703
 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 465a8b7c41f42a5c64036adf4619b34d7fb3ad0947c0662c1c5c372b41649475
+F src/json.c 3d790a2822cf3938d808dd4c82713e640f2fc410504b0f853dc32b8fa585bad4
 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 cb8e55b59113d0102c50db0a43b1b59d531cdcb12a7cce4c4c9a428c7c6e1adf
-R 8b2a817ae31399c7deb32904feb440aa
+P 82036fafa175e798fd32b3dc4ad043fc2bbe2bb2af17781f12dcb4d23a233865
+R cfe70b6eb98b5198569bd46361e5c403
 U drh
-Z 77bd223cb339720304c49139be84aed5
+Z 24e4693854a4d68b165699d3ce0f66fc
 # Remove this line to create a well-formed Fossil manifest.
index 5b59c597c44ea0983cd62b1242904db4abd75cc4..5e313593233b2eaf2e1dd8b6a6d19b2f6a29f915 100644 (file)
@@ -1 +1 @@
-82036fafa175e798fd32b3dc4ad043fc2bbe2bb2af17781f12dcb4d23a233865
+f8659b700c0088abe19ce65fec032c1005a1f750566488f4578256d41558770c
index da514afd5a5d5be04458468eb674fb84abc7d78a..73912a4e1fd3068af25a93212c589d4334f60413 100644 (file)
@@ -4166,6 +4166,7 @@ json_extract_error:
 #define JSON_MERGE_BADTARGET   1     /* Malformed TARGET blob */
 #define JSON_MERGE_BADPATCH    2     /* Malformed PATCH blob */
 #define JSON_MERGE_OOM         3     /* Out-of-memory condition */
+#define JSON_MERGE_TOODEEP     4     /* Nested too deep */
 
 /*
 ** RFC-7396 MergePatch for two JSONB blobs.
@@ -4217,7 +4218,8 @@ static int jsonMergePatch(
   JsonParse *pTarget,      /* The JSON parser that contains the TARGET */
   u32 iTarget,             /* Index of TARGET in pTarget->aBlob[] */
   const JsonParse *pPatch, /* The PATCH */
-  u32 iPatch               /* Index of PATCH in pPatch->aBlob[] */
+  u32 iPatch,              /* Index of PATCH in pPatch->aBlob[] */
+  u32 iDepth               /* Nesting depth */
 ){
   u8 x;             /* Type of a single node */
   u32 n, sz=0;      /* Return values from jsonbPayloadSize() */
@@ -4326,7 +4328,8 @@ static int jsonMergePatch(
         /* Algorithm line 12 */
         int rc, savedDelta = pTarget->delta;
         pTarget->delta = 0;
-        rc = jsonMergePatch(pTarget, iTValue, pPatch, iPValue);
+        if( iDepth>=JSON_MAX_DEPTH ) return JSON_MERGE_TOODEEP;
+        rc = jsonMergePatch(pTarget, iTValue, pPatch, iPValue, iDepth+1);
         if( rc ) return rc;
         pTarget->delta += savedDelta;
       }        
@@ -4347,7 +4350,8 @@ static int jsonMergePatch(
         pTarget->aBlob[iTEnd+szNew] = 0x00;
         savedDelta = pTarget->delta;
         pTarget->delta = 0;
-        rc = jsonMergePatch(pTarget, iTEnd+szNew,pPatch,iPValue);
+        if( iDepth>=JSON_MAX_DEPTH ) return JSON_MERGE_TOODEEP;
+        rc = jsonMergePatch(pTarget, iTEnd+szNew,pPatch,iPValue,iDepth+1);
         if( rc ) return rc;
         pTarget->delta += savedDelta;
       }
@@ -4378,11 +4382,13 @@ static void jsonPatchFunc(
   if( pTarget==0 ) return;
   pPatch = jsonParseFuncArg(ctx, argv[1], 0);
   if( pPatch ){
-    rc = jsonMergePatch(pTarget, 0, pPatch, 0);
+    rc = jsonMergePatch(pTarget, 0, pPatch, 0, 0);
     if( rc==JSON_MERGE_OK ){
       jsonReturnParse(ctx, pTarget);
     }else if( rc==JSON_MERGE_OOM ){
       sqlite3_result_error_nomem(ctx);
+    }else if( rc==JSON_MERGE_TOODEEP ){
+      sqlite3_result_error(ctx, "JSON nested too deep", -1);
     }else{
       sqlite3_result_error(ctx, "malformed JSON", -1);
     }