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
This commit is contained in:
parent
e97c9ff49a
commit
ff6d50e973
@ -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;
|
||||
}
|
||||
|
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
||||
C Smaller\sand\sfaster\simplementation\sof\sexprMightBeIndexed().
|
||||
D 2017-04-11T18:06:48.387
|
||||
C Limit\sthe\sdepth\sof\srecursion\sfor\svalid\sJSON\sin\sthe\sJSON1\sextension\sin\sorder\nto\savoid\susing\sexcess\sstack\sspace\sin\sthe\srecursive\sdescent\sparser.\nFix\sfor\sticket\s[981329adeef51011052667a9].
|
||||
D 2017-04-11T18:55:05.542
|
||||
F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a
|
||||
@ -218,7 +218,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 70d49f69ce61e54a83a29e425e704ca3e7e42e6bd9a7cf3c112d0ad995f6560b
|
||||
F ext/misc/json1.c 18d80526c34e3eab8adf6a86f7e45b873c19b33d341e76993590a3fca9aefa14
|
||||
F ext/misc/memvfs.c e5225bc22e79dde6b28380f3a068ddf600683a33
|
||||
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
|
||||
F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e
|
||||
@ -911,7 +911,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 c0897616f32d95431f37fd291cb78742181980ac
|
||||
F test/json101.test 9e68ac5c7cb3fabe22677d919ca025f80f27dde37f4e760b43f9720179ee466c
|
||||
F test/json102.test eeb54efa221e50b74a2d6fb9259963b48d7414dca3ce2fdfdeed45cb28487bc1
|
||||
F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0
|
||||
F test/json104.test 877d5845f6303899b7889ea5dd1bea99076e3100574d5c536082245c5805dcaa
|
||||
@ -1571,7 +1571,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 4143650c4ce32289d2301cdfc69bb10877246420f656bed122886f6803fc956a
|
||||
R 1aa45dcbe6873a793fc57d44af855002
|
||||
P 76cd611d41465fcec61c21520d55172cb236530f38386b7d4a5544ba87de2353
|
||||
R 4121191f9cbabfb85c1e92872e6e98a5
|
||||
U drh
|
||||
Z c24847878c6bf2e9fe8bedbea41e582e
|
||||
Z 8a8f0ee4e24e0270c8727f53d830c8c6
|
||||
|
@ -1 +1 @@
|
||||
76cd611d41465fcec61c21520d55172cb236530f38386b7d4a5544ba87de2353
|
||||
1f68c184596912d742b50b1ca38252a9e783aacf121619a27b17a7ae9f6df041
|
@ -688,5 +688,29 @@ 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user