File: 43-JSON-3.patch

package info (click to toggle)
sqlite3 3.16.2-5+deb9u1
  • links: PTS
  • area: main
  • in suites: stretch
  • size: 88,416 kB
  • sloc: ansic: 195,593; tcl: 14,245; sh: 10,163; yacc: 1,246; makefile: 1,058; cs: 299; cpp: 128
file content (130 lines) | stat: -rw-r--r-- 4,099 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
Index: sqlite3/ext/misc/json1.c
==================================================================
--- sqlite3/ext/misc/json1.c
+++ sqlite3/ext/misc/json1.c
@@ -88,10 +88,11 @@
 #ifndef SQLITE_AMALGAMATION
   /* Unsigned integer types.  These are already defined in the sqliteInt.h,
   ** but the definitions need to be repeated for separate compilation. */
   typedef sqlite3_uint64 u64;
   typedef unsigned int u32;
+  typedef unsigned short int u16;
   typedef unsigned char u8;
 #endif
 
 /* Objects */
 typedef struct JsonString JsonString;
@@ -165,12 +166,22 @@
   JsonNode *aNode;   /* Array of nodes containing the parse */
   const char *zJson; /* Original JSON string */
   u32 *aUp;          /* Index of parent of each node */
   u8 oom;            /* Set to true if out of memory */
   u8 nErr;           /* Number of errors seen */
+  u16 iDepth;        /* Nesting depth */
 };
 
+/*
+** Maximum nesting depth of JSON for this implementation.
+**
+** This limit is needed to avoid a stack overflow in the recursive
+** descent parser.  A depth of 2000 is far deeper than any sane JSON
+** should go.
+*/
+#define JSON_MAX_DEPTH  2000
+
 /**************************************************************************
 ** Utility routines for dealing with JsonString objects
 **************************************************************************/
 
 /* Set the JsonString object to an empty string
@@ -734,12 +745,14 @@
     /* Parse object */
     iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
     if( iThis<0 ) return -1;
     for(j=i+1;;j++){
       while( safe_isspace(z[j]) ){ j++; }
+      if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
       x = jsonParseValue(pParse, j);
       if( x<0 ){
+        pParse->iDepth--;
         if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
         return -1;
       }
       if( pParse->oom ) return -1;
       pNode = &pParse->aNode[pParse->nNode-1];
@@ -748,10 +761,11 @@
       j = x;
       while( safe_isspace(z[j]) ){ j++; }
       if( z[j]!=':' ) return -1;
       j++;
       x = jsonParseValue(pParse, j);
+      pParse->iDepth--;
       if( x<0 ) return -1;
       j = x;
       while( safe_isspace(z[j]) ){ j++; }
       c = z[j];
       if( c==',' ) continue;
@@ -764,11 +778,13 @@
     /* Parse array */
     iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
     if( iThis<0 ) return -1;
     for(j=i+1;;j++){
       while( safe_isspace(z[j]) ){ j++; }
+      if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
       x = jsonParseValue(pParse, j);
+      pParse->iDepth--;
       if( x<0 ){
         if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
         return -1;
       }
       j = x;
@@ -887,10 +903,11 @@
   if( zJson==0 ) return 1;
   pParse->zJson = zJson;
   i = jsonParseValue(pParse, 0);
   if( pParse->oom ) i = -1;
   if( i>0 ){
+    assert( pParse->iDepth==0 );
     while( safe_isspace(zJson[i]) ) i++;
     if( zJson[i] ) i = -1;
   }
   if( i<=0 ){
     if( pCtx!=0 ){

Index: sqlite3/test/json101.test
==================================================================
--- sqlite3/test/json101.test
+++ sqlite3/test/json101.test
@@ -695,7 +695,31 @@
 } {0}
 do_execsql_test json-10.95 {
   SELECT json_valid('" \~ "');
 } {0}
 
+#--------------------------------------------------------------------------
+# 2017-04-11.  https://www.sqlite.org/src/info/981329adeef51011
+# Stack overflow on deeply nested JSON.
+#
+# The following tests confirm that deeply nested JSON is considered invalid.
+#
+do_execsql_test json-11.0 {
+  /* Shallow enough to be parsed */
+  SELECT json_valid(printf('%.2000c0%.2000c','[',']'));
+} {1}
+do_execsql_test json-11.1 {
+  /* Too deep by one */
+  SELECT json_valid(printf('%.2001c0%.2001c','[',']'));
+} {0}
+do_execsql_test json-11.2 {
+  /* Shallow enough to be parsed { */
+  SELECT json_valid(replace(printf('%.2000c0%.2000c','[','}'),'[','{"a":'));
+  /* } */
+} {1}
+do_execsql_test json-11.3 {
+  /* Too deep by one { */
+  SELECT json_valid(replace(printf('%.2001c0%.2001c','[','}'),'[','{"a":'));
+  /* } */
+} {0}
 
 finish_test