]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Permit JSON5 whitespace in all contexts of objects and arrays.
authordrh <>
Thu, 27 Apr 2023 13:44:26 +0000 (13:44 +0000)
committerdrh <>
Thu, 27 Apr 2023 13:44:26 +0000 (13:44 +0000)
FossilOrigin-Name: 93f3ab26b57c0469862a56e97d4b3c796b27f9f582046fcff1f2aa8d8910c550

manifest
manifest.uuid
src/json.c

index e797d7023808574faad5ec67c74337339ca825e0..a76a4753ef77f5718cf06253167b8f6979bb1d81 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Translate\sJSON5-only\sstring\sliteral\sescape\ssequences\sinto\sthe\sJSON\sequivalents.
-D 2023-04-27T12:24:00.195
+C Permit\sJSON5\swhitespace\sin\sall\scontexts\sof\sobjects\sand\sarrays.
+D 2023-04-27T13:44:26.660
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -592,7 +592,7 @@ F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
 F src/hwtime.h b638809e083b601b618df877b2e89cb87c2a47a01f4def10be4c4ebb54664ac7
 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
 F src/insert.c a8de1db43335fc4946370a7a7e47d89975ad678ddb15078a150e993ba2fb37d4
-F src/json.c e872bb2ba63296c21dd62f83557d504bfb94f299a6591ec735cd4a9aed4e321b
+F src/json.c 28ca7f26c211e0fd705d06d9036de59304f9a3dd5e69e3745a688aafd8c618ae
 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
 F src/loadext.c be5af440f3192c58681b5d43167dbca3ccbfce394d89faa22378a14264781136
 F src/main.c 09bc5191f75dc48fc4dfddda143cb864c0c3dbc3297eb9a9c8e01fea58ff847d
@@ -2063,8 +2063,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 9508efa9d61c0ff0eb73100dd52889dadc5fa2a2091b944a9b8a74e8a5c50e82
-R 672753aa30f1f89635383bf8b5e62624
+P 14e82f36eed31af1237898728bf353b968523c62b1f8d1d90dbbabd92d0c2834
+R 37b7a9f174ccda66654bba8268903617
 U drh
-Z aa11f958e9e420359b5624437ca5455e
+Z 18c492aceae37854acd7e6823a29d2b5
 # Remove this line to create a well-formed Fossil manifest.
index 4badfeac1ab3c59dfa1094c2deca24182b50b019..2f3e3c7fd14bfe79cdb00d3a68dd7db158e1e531 100644 (file)
@@ -1 +1 @@
-14e82f36eed31af1237898728bf353b968523c62b1f8d1d90dbbabd92d0c2834
\ No newline at end of file
+93f3ab26b57c0469862a56e97d4b3c796b27f9f582046fcff1f2aa8d8910c550
\ No newline at end of file
index 0cbcac3c4edb00f604ff4a74786d312ad54d5c2b..dbc1c6b833684ab6cd4ab99cacad47e467c44ca4 100644 (file)
@@ -136,6 +136,7 @@ struct JsonParse {
   u8 oom;            /* Set to true if out of memory */
   u8 has5;           /* True if input has JSON5 features */
   int nJson;         /* Length of the zJson string in bytes */
+  u32 iErr;          /* Error location in zJson[] */
   u32 iHold;         /* Replace cache line with the lowest iHold value */
 };
 
@@ -945,7 +946,7 @@ static int json5Whitespace(const char *zIn){
           for(j=n+3; z[j]!='/' || z[j-1]!='*'; j++){
             if( z[j]==0 ) goto whitespace_done;
           }
-          n += j;
+          n += j+1;
           break;
         }else if( z[n+1]=='/' ){
           int j;
@@ -1032,9 +1033,14 @@ static const struct NanInfName {
 ** Parse a single JSON value which begins at pParse->zJson[i].  Return the
 ** index of the first character past the end of the value parsed.
 **
-** Return negative for a syntax error.  Special cases:  return -2 if the
-** first non-whitespace character is '}' and return -3 if the first
-** non-whitespace character is ']'.
+** Special return values:
+**
+**      0    End if input
+**     -1    Syntax error
+**     -2    '}' seen
+**     -3    ']' seen
+**     -4    ',' seen
+**     -5    ':' seen
 */
 static int jsonParseValue(JsonParse *pParse, u32 i){
   char c;
@@ -1050,12 +1056,12 @@ json_parse_restart:
     iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
     if( iThis<0 ) return -1;
     for(j=i+1;;j++){
-      while( fast_isspace(z[j]) ){ j++; }
       if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
       x = jsonParseValue(pParse, j);
-      if( x<0 ){
+      if( x<=0 ){
         pParse->iDepth--;
         if( x==(-2) ){
+          j = pParse->iErr;
           if( pParse->nNode!=(u32)iThis+1 ) pParse->has5 = 1;
           break;
         }
@@ -1066,18 +1072,33 @@ json_parse_restart:
       if( pNode->eType!=JSON_STRING ) return -1;
       pNode->jnFlags |= JNODE_LABEL;
       j = x;
-      while( fast_isspace(z[j]) ){ j++; }
-      if( z[j]!=':' ) return -1;
-      j++;
+      if( z[j]==':' ){
+        j++;
+      }else{
+        x = jsonParseValue(pParse, j);
+        if( x!=(-5) ) return -1;
+        j = pParse->iErr+1;
+      }
       x = jsonParseValue(pParse, j);
       pParse->iDepth--;
       if( x<0 ) return -1;
       j = x;
-      while( fast_isspace(z[j]) ){ j++; }
-      c = z[j];
-      if( c==',' ) continue;
-      if( c!='}' ) return -1;
-      break;
+      if( z[j]==',' ){
+        continue;
+      }else if( z[j]=='}' ){
+        break;
+      }else{
+        x = jsonParseValue(pParse, j);
+        if( x==(-4) ){
+          j = pParse->iErr;
+          continue;
+        }
+        if( x==(-2) ){
+          j = pParse->iErr;
+          break;
+        }
+      }
+      return -1;
     }
     pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
     return j+1;
@@ -1088,23 +1109,34 @@ json_parse_restart:
     if( iThis<0 ) return -1;
     memset(&pParse->aNode[iThis].u, 0, sizeof(pParse->aNode[iThis].u));
     for(j=i+1;;j++){
-      while( fast_isspace(z[j]) ){ j++; }
       if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
       x = jsonParseValue(pParse, j);
       pParse->iDepth--;
       if( x<0 ){
         if( x==(-3) ){
+          j = pParse->iErr;
           if( pParse->nNode!=(u32)iThis+1 ) pParse->has5 = 1;
           break;
         }
         return -1;
       }
       j = x;
-      while( fast_isspace(z[j]) ){ j++; }
-      c = z[j];
-      if( c==',' ) continue;
-      if( c!=']' ) return -1;
-      break;
+      if( z[j]==',' ){
+        continue;
+      }else if( z[j]==']' ){
+        break;
+      }else{
+        x = jsonParseValue(pParse, j);
+        if( x==(-4) ){
+          j = pParse->iErr;
+          continue;
+        }
+        if( x==(-3) ){
+          j = pParse->iErr;
+          break;
+        }
+      }
+      return -1;
     }
     pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
     return j+1;
@@ -1260,11 +1292,21 @@ json_parse_restart:
     return j;
   }
   case '}': {
+    pParse->iErr = i;
     return -2;  /* End of {...} */
   }
   case ']': {
+    pParse->iErr = i;
     return -3;  /* End of [...] */
   }
+  case ',': {
+    pParse->iErr = i;
+    return -4;  /* List separator */
+  }
+  case ':': {
+    pParse->iErr = i;
+    return -5;  /* Object label/value separator */
+  }
   case 0: {
     return 0;   /* End of file */
   }
@@ -1334,7 +1376,11 @@ static int jsonParse(
   if( i>0 ){
     assert( pParse->iDepth==0 );
     while( fast_isspace(zJson[i]) ) i++;
-    if( zJson[i] ) i = -1;
+    if( zJson[i] ){
+      i += json5Whitespace(&zJson[i]);
+      if( zJson[i] ) return -1;
+      pParse->has5 = 1;
+    }
   }
   if( i<=0 ){
     if( pCtx!=0 ){