Index: ext/misc/json1.c ================================================================== --- ext/misc/json1.c +++ 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; @@ -167,12 +168,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 @@ -733,12 +744,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]; @@ -747,10 +760,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; @@ -763,11 +777,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; @@ -883,10 +899,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: test/json101.test ================================================================== --- test/json101.test +++ test/json101.test @@ -686,7 +686,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