diff options
author | drh <drh@noemail.net> | 2017-04-11 18:55:05 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2017-04-11 18:55:05 +0000 |
commit | ff6d50e973f597c1ab3ead0ea7d553d41b608a8d (patch) | |
tree | a63e74bdc4b935ac43608a15523e8ae49bbf5993 /ext/misc/json1.c | |
parent | e97c9ff49adaa4906f935f2e52e355110c806218 (diff) | |
download | sqlite-ff6d50e973f597c1ab3ead0ea7d553d41b608a8d.tar.gz sqlite-ff6d50e973f597c1ab3ead0ea7d553d41b608a8d.zip |
Limit the depth of recursion for valid JSON in the JSON1 extension in order
to avoid using excess stack space in the recursive descent parser.
Fix for ticket [981329adeef51011052667a9].
FossilOrigin-Name: 1f68c184596912d742b50b1ca38252a9e783aacf121619a27b17a7ae9f6df041
Diffstat (limited to 'ext/misc/json1.c')
-rw-r--r-- | ext/misc/json1.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/ext/misc/json1.c b/ext/misc/json1.c index 0d1b9a464..486eaa428 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -90,6 +90,7 @@ static const char jsonIsSpace[] = { ** 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 @@ -169,8 +170,18 @@ struct JsonParse { 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 **************************************************************************/ @@ -735,8 +746,10 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ 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; } @@ -749,6 +762,7 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ 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++; } @@ -765,7 +779,9 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ 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; @@ -885,6 +901,7 @@ static int jsonParse( 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; } |