]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix the JSON1 extension so that the JSON validator correctly rejects malformed
authordrh <drh@noemail.net>
Mon, 7 Nov 2016 13:37:28 +0000 (13:37 +0000)
committerdrh <drh@noemail.net>
Mon, 7 Nov 2016 13:37:28 +0000 (13:37 +0000)
backslash escapes within string literals.

FossilOrigin-Name: 7a63539169a384960e30a63e0c8e9b0f07fa431e

ext/misc/json1.c
manifest
manifest.uuid
test/json101.test

index 61c52ebe61eb81c41d795461660949c925782a0c..839e133bf2786f0bde05e04144450a98fe042b25 100644 (file)
@@ -49,13 +49,15 @@ SQLITE_EXTENSION_INIT1
 #ifdef sqlite3Isdigit
    /* Use the SQLite core versions if this routine is part of the
    ** SQLite amalgamation */
-#  define safe_isdigit(x) sqlite3Isdigit(x)
-#  define safe_isalnum(x) sqlite3Isalnum(x)
+#  define safe_isdigit(x)  sqlite3Isdigit(x)
+#  define safe_isalnum(x)  sqlite3Isalnum(x)
+#  define safe_isxdigit(x) sqlite3Isxdigit(x)
 #else
    /* Use the standard library for separate compilation */
 #include <ctype.h>  /* amalgamator: keep */
-#  define safe_isdigit(x) isdigit((unsigned char)(x))
-#  define safe_isalnum(x) isalnum((unsigned char)(x))
+#  define safe_isdigit(x)  isdigit((unsigned char)(x))
+#  define safe_isalnum(x)  isalnum((unsigned char)(x))
+#  define safe_isxdigit(x) isxdigit((unsigned char)(x))
 #endif
 
 /*
@@ -702,6 +704,15 @@ static int jsonParseAddNode(
   return pParse->nNode++;
 }
 
+/*
+** Return true if z[] begins with 4 (or more) hexadecimal digits
+*/
+static int jsonIs4Hex(const char *z){
+  int i;
+  for(i=0; i<4; i++) if( !safe_isxdigit(z[i]) ) return 0;
+  return 1;
+}
+
 /*
 ** 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.
@@ -776,8 +787,13 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
       if( c==0 ) return -1;
       if( c=='\\' ){
         c = pParse->zJson[++j];
-        if( c==0 ) return -1;
-        jnFlags = JNODE_ESCAPE;
+        if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
+           || c=='n' || c=='r' || c=='t'
+           || (c=='u' && jsonIs4Hex(pParse->zJson+j+1)) ){
+          jnFlags = JNODE_ESCAPE;
+        }else{
+          return -1;
+        }
       }else if( c=='"' ){
         break;
       }
index daade9e2e42301619b252abb3ceb4d0153b65233..8ea3d627b0fb2e1491a67ba3742b80e069b6cb19 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Avoid\sa\scrash\sthat\scan\soccur\safter\san\sobscure\sOOM\sin\sthe\sbuilt-in\sINSTR()\nfunction.
-D 2016-11-04T12:05:29.977
+C Fix\sthe\sJSON1\sextension\sso\sthat\sthe\sJSON\svalidator\scorrectly\srejects\smalformed\nbackslash\sescapes\swithin\sstring\sliterals.
+D 2016-11-07T13:37:28.861
 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408
@@ -213,7 +213,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
 F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25
 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
-F ext/misc/json1.c 9799e4252b305edcbe659329eec3ca80ed85f968
+F ext/misc/json1.c 813a2ff17b3e951a4b875ef79b5f4a0543cb0a2d
 F ext/misc/memvfs.c e5225bc22e79dde6b28380f3a068ddf600683a33
 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
 F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e
@@ -886,7 +886,7 @@ F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307
 F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa
 F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
 F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
-F test/json101.test 865776ed8580703e1684fe4b8ee2e473333bb121
+F test/json101.test c0897616f32d95431f37fd291cb78742181980ac
 F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a
 F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0
 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
@@ -1530,7 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P afbbb6c66a85ff3f4c8dce677e0892a2a51d2b8e
-R 54226d0f905e5410be62ada12fc4c3f1
-U dan
-Z 547f4b4fa61cca40324639e3127db72b
+P b86b79c442a58d10aa005ba4f34095375a88d242
+R 7a809bd65e85c52e8075f2c4e33138f7
+U drh
+Z 3735bc72c61a220065b296aebe8a3b9c
index e7888e69700d0790ed7aad53bb04ce140a03e84a..5fedc2cefcebb2eaa65acb24cbf7d50ce768cb4f 100644 (file)
@@ -1 +1 @@
-b86b79c442a58d10aa005ba4f34095375a88d242
\ No newline at end of file
+7a63539169a384960e30a63e0c8e9b0f07fa431e
\ No newline at end of file
index 3ee007c1cbd807cea705305d23140395ec3551b1..37123eef1d7d0e866b4cdab778a946af4805f272 100644 (file)
@@ -382,8 +382,311 @@ do_catchsql_test json-9.7 {
   SELECT json_quote()
 } {1 {wrong number of arguments to function json_quote()}}
 
-
-
+# Make sure only valid backslash-escapes are accepted.
+#
+do_execsql_test json-10.1 {
+  SELECT json_valid('" \  "');
+} {0}
+do_execsql_test json-10.2 {
+  SELECT json_valid('" \! "');
+} {0}
+do_execsql_test json-10.3 {
+  SELECT json_valid('" \" "');
+} {1}
+do_execsql_test json-10.4 {
+  SELECT json_valid('" \# "');
+} {0}
+do_execsql_test json-10.5 {
+  SELECT json_valid('" \$ "');
+} {0}
+do_execsql_test json-10.6 {
+  SELECT json_valid('" \% "');
+} {0}
+do_execsql_test json-10.7 {
+  SELECT json_valid('" \& "');
+} {0}
+do_execsql_test json-10.8 {
+  SELECT json_valid('" \'' "');
+} {0}
+do_execsql_test json-10.9 {
+  SELECT json_valid('" \( "');
+} {0}
+do_execsql_test json-10.10 {
+  SELECT json_valid('" \) "');
+} {0}
+do_execsql_test json-10.11 {
+  SELECT json_valid('" \* "');
+} {0}
+do_execsql_test json-10.12 {
+  SELECT json_valid('" \+ "');
+} {0}
+do_execsql_test json-10.13 {
+  SELECT json_valid('" \, "');
+} {0}
+do_execsql_test json-10.14 {
+  SELECT json_valid('" \- "');
+} {0}
+do_execsql_test json-10.15 {
+  SELECT json_valid('" \. "');
+} {0}
+do_execsql_test json-10.16 {
+  SELECT json_valid('" \/ "');
+} {1}
+do_execsql_test json-10.17 {
+  SELECT json_valid('" \0 "');
+} {0}
+do_execsql_test json-10.18 {
+  SELECT json_valid('" \1 "');
+} {0}
+do_execsql_test json-10.19 {
+  SELECT json_valid('" \2 "');
+} {0}
+do_execsql_test json-10.20 {
+  SELECT json_valid('" \3 "');
+} {0}
+do_execsql_test json-10.21 {
+  SELECT json_valid('" \4 "');
+} {0}
+do_execsql_test json-10.22 {
+  SELECT json_valid('" \5 "');
+} {0}
+do_execsql_test json-10.23 {
+  SELECT json_valid('" \6 "');
+} {0}
+do_execsql_test json-10.24 {
+  SELECT json_valid('" \7 "');
+} {0}
+do_execsql_test json-10.25 {
+  SELECT json_valid('" \8 "');
+} {0}
+do_execsql_test json-10.26 {
+  SELECT json_valid('" \9 "');
+} {0}
+do_execsql_test json-10.27 {
+  SELECT json_valid('" \: "');
+} {0}
+do_execsql_test json-10.28 {
+  SELECT json_valid('" \; "');
+} {0}
+do_execsql_test json-10.29 {
+  SELECT json_valid('" \< "');
+} {0}
+do_execsql_test json-10.30 {
+  SELECT json_valid('" \= "');
+} {0}
+do_execsql_test json-10.31 {
+  SELECT json_valid('" \> "');
+} {0}
+do_execsql_test json-10.32 {
+  SELECT json_valid('" \? "');
+} {0}
+do_execsql_test json-10.33 {
+  SELECT json_valid('" \@ "');
+} {0}
+do_execsql_test json-10.34 {
+  SELECT json_valid('" \A "');
+} {0}
+do_execsql_test json-10.35 {
+  SELECT json_valid('" \B "');
+} {0}
+do_execsql_test json-10.36 {
+  SELECT json_valid('" \C "');
+} {0}
+do_execsql_test json-10.37 {
+  SELECT json_valid('" \D "');
+} {0}
+do_execsql_test json-10.38 {
+  SELECT json_valid('" \E "');
+} {0}
+do_execsql_test json-10.39 {
+  SELECT json_valid('" \F "');
+} {0}
+do_execsql_test json-10.40 {
+  SELECT json_valid('" \G "');
+} {0}
+do_execsql_test json-10.41 {
+  SELECT json_valid('" \H "');
+} {0}
+do_execsql_test json-10.42 {
+  SELECT json_valid('" \I "');
+} {0}
+do_execsql_test json-10.43 {
+  SELECT json_valid('" \J "');
+} {0}
+do_execsql_test json-10.44 {
+  SELECT json_valid('" \K "');
+} {0}
+do_execsql_test json-10.45 {
+  SELECT json_valid('" \L "');
+} {0}
+do_execsql_test json-10.46 {
+  SELECT json_valid('" \M "');
+} {0}
+do_execsql_test json-10.47 {
+  SELECT json_valid('" \N "');
+} {0}
+do_execsql_test json-10.48 {
+  SELECT json_valid('" \O "');
+} {0}
+do_execsql_test json-10.49 {
+  SELECT json_valid('" \P "');
+} {0}
+do_execsql_test json-10.50 {
+  SELECT json_valid('" \Q "');
+} {0}
+do_execsql_test json-10.51 {
+  SELECT json_valid('" \R "');
+} {0}
+do_execsql_test json-10.52 {
+  SELECT json_valid('" \S "');
+} {0}
+do_execsql_test json-10.53 {
+  SELECT json_valid('" \T "');
+} {0}
+do_execsql_test json-10.54 {
+  SELECT json_valid('" \U "');
+} {0}
+do_execsql_test json-10.55 {
+  SELECT json_valid('" \V "');
+} {0}
+do_execsql_test json-10.56 {
+  SELECT json_valid('" \W "');
+} {0}
+do_execsql_test json-10.57 {
+  SELECT json_valid('" \X "');
+} {0}
+do_execsql_test json-10.58 {
+  SELECT json_valid('" \Y "');
+} {0}
+do_execsql_test json-10.59 {
+  SELECT json_valid('" \Z "');
+} {0}
+do_execsql_test json-10.60 {
+  SELECT json_valid('" \[ "');
+} {0}
+do_execsql_test json-10.61 {
+  SELECT json_valid('" \\ "');
+} {1}
+do_execsql_test json-10.62 {
+  SELECT json_valid('" \] "');
+} {0}
+do_execsql_test json-10.63 {
+  SELECT json_valid('" \^ "');
+} {0}
+do_execsql_test json-10.64 {
+  SELECT json_valid('" \_ "');
+} {0}
+do_execsql_test json-10.65 {
+  SELECT json_valid('" \` "');
+} {0}
+do_execsql_test json-10.66 {
+  SELECT json_valid('" \a "');
+} {0}
+do_execsql_test json-10.67 {
+  SELECT json_valid('" \b "');
+} {1}
+do_execsql_test json-10.68 {
+  SELECT json_valid('" \c "');
+} {0}
+do_execsql_test json-10.69 {
+  SELECT json_valid('" \d "');
+} {0}
+do_execsql_test json-10.70 {
+  SELECT json_valid('" \e "');
+} {0}
+do_execsql_test json-10.71 {
+  SELECT json_valid('" \f "');
+} {1}
+do_execsql_test json-10.72 {
+  SELECT json_valid('" \g "');
+} {0}
+do_execsql_test json-10.73 {
+  SELECT json_valid('" \h "');
+} {0}
+do_execsql_test json-10.74 {
+  SELECT json_valid('" \i "');
+} {0}
+do_execsql_test json-10.75 {
+  SELECT json_valid('" \j "');
+} {0}
+do_execsql_test json-10.76 {
+  SELECT json_valid('" \k "');
+} {0}
+do_execsql_test json-10.77 {
+  SELECT json_valid('" \l "');
+} {0}
+do_execsql_test json-10.78 {
+  SELECT json_valid('" \m "');
+} {0}
+do_execsql_test json-10.79 {
+  SELECT json_valid('" \n "');
+} {1}
+do_execsql_test json-10.80 {
+  SELECT json_valid('" \o "');
+} {0}
+do_execsql_test json-10.81 {
+  SELECT json_valid('" \p "');
+} {0}
+do_execsql_test json-10.82 {
+  SELECT json_valid('" \q "');
+} {0}
+do_execsql_test json-10.83 {
+  SELECT json_valid('" \r "');
+} {1}
+do_execsql_test json-10.84 {
+  SELECT json_valid('" \s "');
+} {0}
+do_execsql_test json-10.85 {
+  SELECT json_valid('" \t "');
+} {1}
+do_execsql_test json-10.86.0 {
+  SELECT json_valid('" \u "');
+} {0}
+do_execsql_test json-10.86.1 {
+  SELECT json_valid('" \ua "');
+} {0}
+do_execsql_test json-10.86.2 {
+  SELECT json_valid('" \uab "');
+} {0}
+do_execsql_test json-10.86.3 {
+  SELECT json_valid('" \uabc "');
+} {0}
+do_execsql_test json-10.86.4 {
+  SELECT json_valid('" \uabcd "');
+} {1}
+do_execsql_test json-10.86.5 {
+  SELECT json_valid('" \uFEDC "');
+} {1}
+do_execsql_test json-10.86.6 {
+  SELECT json_valid('" \u1234 "');
+} {1}
+do_execsql_test json-10.87 {
+  SELECT json_valid('" \v "');
+} {0}
+do_execsql_test json-10.88 {
+  SELECT json_valid('" \w "');
+} {0}
+do_execsql_test json-10.89 {
+  SELECT json_valid('" \x "');
+} {0}
+do_execsql_test json-10.90 {
+  SELECT json_valid('" \y "');
+} {0}
+do_execsql_test json-10.91 {
+  SELECT json_valid('" \z "');
+} {0}
+do_execsql_test json-10.92 {
+  SELECT json_valid('" \{ "');
+} {0}
+do_execsql_test json-10.93 {
+  SELECT json_valid('" \| "');
+} {0}
+do_execsql_test json-10.94 {
+  SELECT json_valid('" \} "');
+} {0}
+do_execsql_test json-10.95 {
+  SELECT json_valid('" \~ "');
+} {0}
 
 
 finish_test