]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Avoid unsigned integer overflow when evaluating an array index in a
authordrh <>
Tue, 27 Jan 2026 23:33:42 +0000 (23:33 +0000)
committerdrh <>
Tue, 27 Jan 2026 23:33:42 +0000 (23:33 +0000)
JSON path expression.
[forum:/forumpost/2026-01-27T14:18:49z|Forum post 2026-01-27T14:18:49z].

FossilOrigin-Name: 631c8d44cd1624ddc45babd3f0d810908c2a368784744262042c63506ff2e333

manifest
manifest.uuid
src/json.c
test/json102.test
test/json105.test

index 10bf2c7a56c97157a0cc4fd70937f7c620effc33..7f9220a2c7045606ec222e633b88deda2f6525e8 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Improved\sbyte-code\scoverage\stesting\sverification\sin\sthe\smerge\salgorithm.
-D 2026-01-27T22:27:14.946
+C Avoid\sunsigned\sinteger\soverflow\swhen\sevaluating\san\sarray\sindex\sin\sa\nJSON\spath\sexpression.\n[forum:/forumpost/2026-01-27T14:18:49z|Forum\spost\s2026-01-27T14:18:49z].
+D 2026-01-27T23:33:42.066
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -699,7 +699,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 519fa46cc3e11d836c264c628ca9ca537ce6f18042151cf7a5c71e3ac5a4a970
+F src/json.c af766b62caee01c735cfe7795cc91ffea5a5e1c555a5d8a9aa5a301f00a1b0ad
 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
 F src/loadext.c 56a542244fbefc739a2ef57fac007c16b2aefdb4377f584e9547db2ce3e071f9
 F src/main.c e95aa130478fc98a49181ddf094baab45f319286411129253618efe0008f0dc4
@@ -1354,10 +1354,10 @@ F test/json/json-q1.txt 65f9d1cdcc4cffa9823fb73ed936aae5658700cd001fde448f68bfb9
 F test/json/json-speed-check.sh 7d5898808ce7542762318306ae6075a30f5e7ee115c4a409f487e123afe91d88 x
 F test/json/jsonb-q1.txt 1e180fe6491efab307e318b22879e3a736ac9a96539bbde7911a13ee5b33abc7
 F test/json101.test cf53254f0f0c1399a01b21fc58fee0e63a12a556be91b9ee9faccdb8b82c083c
-F test/json102.test 9b2e5ada10845ff84853b3feaae2ce51ce7145ae458f74c6a6cecc6ef6ee3ae1
+F test/json102.test ea5c9811e408e115c8fc539548deef431fda4924c23cacd79dd4b783f4449f07
 F test/json103.test e626d109cd0bdb8282ec9bf755af3befa50e3e03a255362fc53433d31e1d66d4
 F test/json104.test 1b844a70cddcfa2e4cd81a5db0657b2e61e7f00868310f24f56a9ba0114348c1
-F test/json105.test 043838b56e68f3252a0dcf5be1689016f6f3f05056f8dcfcdc9d074f4d932988
+F test/json105.test 9900caa21888289873bc6c14f5ee41213d28ac9b7ca3395f8afb73d540e80f66
 F test/json106.test 4aed3afd16549045d198a8d9cea00deea96e1f2ecf55864dce96cac558b8abef
 F test/json107.test 59054e815c8f6b67d634d44ace421cf975828fb5651c4460aa66015c8e19d562
 F test/json108.test 0a5f1e2d4b35a1bc33052563d2a5ede03052e2099e58cb424547656c898e0f49
@@ -2193,8 +2193,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
 F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P dabaeeb1dab82eaea2449658b9c4c74af0058e5a64a076dab046902c6efac292
-R 75afb5053416893c324ab21387fcb473
+P e49ec0e24b4765a6a819f3e980b680b9604f6db21aa8112ec4e9b54d82220c00
+R 94cd5dbd82fd2b2e6a88cf73c970cba0
 U drh
-Z 3c56490441974bd50e8ddc69af179ada
+Z 8f074e6ae6c20953c6958faec0931530
 # Remove this line to create a well-formed Fossil manifest.
index 9426c5c9d5b89c1d403d44d3f64b4d981727038c..0b4587fc610a00e7523066a117237e0084873197 100644 (file)
@@ -1 +1 @@
-e49ec0e24b4765a6a819f3e980b680b9604f6db21aa8112ec4e9b54d82220c00
+631c8d44cd1624ddc45babd3f0d810908c2a368784744262042c63506ff2e333
index 90f5031673eb78a80856f913b690398abcc03e3e..794b5406cfe0070788937b41573774607822a9ef 100644 (file)
@@ -3076,28 +3076,32 @@ static u32 jsonLookupStep(
       return rc;
     }
   }else if( zPath[0]=='[' ){
+    u64 kk = 0;
     x = pParse->aBlob[iRoot] & 0x0f;
     if( x!=JSONB_ARRAY )  return JSON_LOOKUP_NOTFOUND;
     n = jsonbPayloadSize(pParse, iRoot, &sz);
-    k = 0;
     i = 1;
     while( sqlite3Isdigit(zPath[i]) ){
-      k = k*10 + zPath[i] - '0';
+      if( kk<0xffffffff ) kk = kk*10 + zPath[i] - '0';
+      /*     ^^^^^^^^^^--- Allow kk to be bigger than any JSON array so that
+      ** we get NOTFOUND instead of PATHERROR, without overflowing kk. */
       i++;
     }
     if( i<2 || zPath[i]!=']' ){
       if( zPath[1]=='#' ){
-        k = jsonbArrayCount(pParse, iRoot);
+        kk = jsonbArrayCount(pParse, iRoot);
         i = 2;
         if( zPath[2]=='-' && sqlite3Isdigit(zPath[3]) ){
-          unsigned int nn = 0;
+          u64 nn = 0;
           i = 3;
           do{
-            nn = nn*10 + zPath[i] - '0';
+            if( nn<0xffffffff ) nn = nn*10 + zPath[i] - '0';
+            /*     ^^^^^^^^^^--- Allow nn to be bigger than any JSON array to
+            ** get NOTFOUND instead of PATHERROR, without overflowing nn. */
             i++;
           }while( sqlite3Isdigit(zPath[i]) );
-          if( nn>k ) return JSON_LOOKUP_NOTFOUND;
-          k -= nn;
+          if( nn>kk ) return JSON_LOOKUP_NOTFOUND;
+          kk -= nn;
         }
         if( zPath[i]!=']' ){
           return JSON_LOOKUP_PATHERROR;
@@ -3109,18 +3113,18 @@ static u32 jsonLookupStep(
     j = iRoot+n;
     iEnd = j+sz;
     while( j<iEnd ){
-      if( k==0 ){
+      if( kk==0 ){
         rc = jsonLookupStep(pParse, j, &zPath[i+1], 0);
         if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot);
         return rc;
       }
-      k--;
+      kk--;
       n = jsonbPayloadSize(pParse, j, &sz);
       if( n==0 ) return JSON_LOOKUP_ERROR;
       j += n+sz;
     }
     if( j>iEnd ) return JSON_LOOKUP_ERROR;
-    if( k>0 ) return JSON_LOOKUP_NOTFOUND;
+    if( kk>0 ) return JSON_LOOKUP_NOTFOUND;
     if( pParse->eEdit>=JEDIT_INS ){
       JsonParse v;
       testcase( pParse->eEdit==JEDIT_INS );
index 54a0e1e0e0408167cc91cd9824d828992a0c6141..54f66a83f0742351e38dd5ec24f05bfe9211c02f 100644 (file)
@@ -375,6 +375,27 @@ do_execsql_test json102-440-3 {
 do_execsql_test json102-440-4 {
   SELECT json(jsonb_remove(jsonb('[0,1,2,3,4]'),'$[2]'));
 } {{[0,1,3,4]}}
+do_execsql_test json102-445-1 {
+  SELECT json_remove('[0,1,2,3,4]','$[5]');
+} {{[0,1,2,3,4]}}
+do_execsql_test json102-445-2 {
+  SELECT json_remove('[0,1,2,3,4]','$[6]');
+} {{[0,1,2,3,4]}}
+do_execsql_test json102-445-3 {
+  SELECT json_remove('[0,1,2,3,4]','$[4294967295]');
+} {{[0,1,2,3,4]}}
+do_execsql_test json102-445-4 {
+  SELECT json_remove('[0,1,2,3,4]','$[4294967296]');
+} {{[0,1,2,3,4]}}
+do_execsql_test json102-445-5 {
+  SELECT json_remove('[0,1,2,3,4]','$[4294967297]');
+} {{[0,1,2,3,4]}}
+do_execsql_test json102-445-6 {
+  SELECT json_remove('[0,1,2,3,4]','$[42949672950]');
+} {{[0,1,2,3,4]}}
+do_execsql_test json102-445-7 {
+  SELECT json_remove('[0,1,2,3,4]','$[42949672960]');
+} {{[0,1,2,3,4]}}
 do_execsql_test json102-450 {
   SELECT json_remove('[0,1,2,3,4]','$[2]','$[0]');
 } {{[1,3,4]}}
index 509db94e1178ef051b8d19474d9642cfa03e5bd8..4a5572cf0f79ebc009f65364be1dfa1d8947d17f 100644 (file)
@@ -29,6 +29,11 @@ json_extract_test 30 {'$.b[#-2]'} {'[2,3]'}
 json_extract_test 31 {'$.b[#-02]'} {'[2,3]'}
 json_extract_test 40 {'$.b[#-3]'} 1
 json_extract_test 50 {'$.b[#-4]'} NULL
+json_extract_test 51 {'$.b[#-4296967295]'} NULL
+json_extract_test 52 {'$.b[#-4296967296]'} NULL
+json_extract_test 53 {'$.b[#-4296967297]'} NULL
+json_extract_test 54 {'$.b[#-42969672950]'} NULL
+json_extract_test 55 {'$.b[#-42969672960]'} NULL
 json_extract_test 60 {'$.b[#-2][#-1]'} 3
 json_extract_test 70 {'$.b[0]','$.b[#-1]'} {'[1,4]'}