1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-29 08:01:23 +03:00

Avoid passing (signed char) values directly to isspace(), isalnum() or isdigit() in json1.c. Cast the value to (unsigned char) first.

FossilOrigin-Name: 6713e35b8a8c997aa2717e86ce6dcd63bb993477
This commit is contained in:
dan
2015-09-17 17:21:09 +00:00
parent cf346d7a9c
commit 2e8f5517f7
4 changed files with 35 additions and 20 deletions

View File

@ -33,6 +33,14 @@ SQLITE_EXTENSION_INIT1
#define UNUSED_PARAM(X) (void)(X) #define UNUSED_PARAM(X) (void)(X)
/*
** Versions of isspace(), isalnum() and isdigit() to which it is safe
** to pass signed char values.
*/
#define safe_isspace(x) isspace((unsigned char)(x))
#define safe_isdigit(x) isdigit((unsigned char)(x))
#define safe_isalnum(x) isalnum((unsigned char)(x))
/* Unsigned integer types */ /* Unsigned integer types */
typedef sqlite3_uint64 u64; typedef sqlite3_uint64 u64;
typedef unsigned int u32; typedef unsigned int u32;
@ -585,14 +593,14 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
int iThis; int iThis;
int x; int x;
JsonNode *pNode; JsonNode *pNode;
while( isspace(pParse->zJson[i]) ){ i++; } while( safe_isspace(pParse->zJson[i]) ){ i++; }
if( (c = pParse->zJson[i])==0 ) return 0; if( (c = pParse->zJson[i])==0 ) return 0;
if( c=='{' ){ if( c=='{' ){
/* Parse object */ /* Parse object */
iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
if( iThis<0 ) return -1; if( iThis<0 ) return -1;
for(j=i+1;;j++){ for(j=i+1;;j++){
while( isspace(pParse->zJson[j]) ){ j++; } while( safe_isspace(pParse->zJson[j]) ){ j++; }
x = jsonParseValue(pParse, j); x = jsonParseValue(pParse, j);
if( x<0 ){ if( x<0 ){
if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1; if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
@ -603,13 +611,13 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
if( pNode->eType!=JSON_STRING ) return -1; if( pNode->eType!=JSON_STRING ) return -1;
pNode->jnFlags |= JNODE_LABEL; pNode->jnFlags |= JNODE_LABEL;
j = x; j = x;
while( isspace(pParse->zJson[j]) ){ j++; } while( safe_isspace(pParse->zJson[j]) ){ j++; }
if( pParse->zJson[j]!=':' ) return -1; if( pParse->zJson[j]!=':' ) return -1;
j++; j++;
x = jsonParseValue(pParse, j); x = jsonParseValue(pParse, j);
if( x<0 ) return -1; if( x<0 ) return -1;
j = x; j = x;
while( isspace(pParse->zJson[j]) ){ j++; } while( safe_isspace(pParse->zJson[j]) ){ j++; }
c = pParse->zJson[j]; c = pParse->zJson[j];
if( c==',' ) continue; if( c==',' ) continue;
if( c!='}' ) return -1; if( c!='}' ) return -1;
@ -622,14 +630,14 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
if( iThis<0 ) return -1; if( iThis<0 ) return -1;
for(j=i+1;;j++){ for(j=i+1;;j++){
while( isspace(pParse->zJson[j]) ){ j++; } while( safe_isspace(pParse->zJson[j]) ){ j++; }
x = jsonParseValue(pParse, j); x = jsonParseValue(pParse, j);
if( x<0 ){ if( x<0 ){
if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1; if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
return -1; return -1;
} }
j = x; j = x;
while( isspace(pParse->zJson[j]) ){ j++; } while( safe_isspace(pParse->zJson[j]) ){ j++; }
c = pParse->zJson[j]; c = pParse->zJson[j];
if( c==',' ) continue; if( c==',' ) continue;
if( c!=']' ) return -1; if( c!=']' ) return -1;
@ -658,17 +666,17 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
return j+1; return j+1;
}else if( c=='n' }else if( c=='n'
&& strncmp(pParse->zJson+i,"null",4)==0 && strncmp(pParse->zJson+i,"null",4)==0
&& !isalnum(pParse->zJson[i+4]) ){ && !safe_isalnum(pParse->zJson[i+4]) ){
jsonParseAddNode(pParse, JSON_NULL, 0, 0); jsonParseAddNode(pParse, JSON_NULL, 0, 0);
return i+4; return i+4;
}else if( c=='t' }else if( c=='t'
&& strncmp(pParse->zJson+i,"true",4)==0 && strncmp(pParse->zJson+i,"true",4)==0
&& !isalnum(pParse->zJson[i+4]) ){ && !safe_isalnum(pParse->zJson[i+4]) ){
jsonParseAddNode(pParse, JSON_TRUE, 0, 0); jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
return i+4; return i+4;
}else if( c=='f' }else if( c=='f'
&& strncmp(pParse->zJson+i,"false",5)==0 && strncmp(pParse->zJson+i,"false",5)==0
&& !isalnum(pParse->zJson[i+5]) ){ && !safe_isalnum(pParse->zJson[i+5]) ){
jsonParseAddNode(pParse, JSON_FALSE, 0, 0); jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
return i+5; return i+5;
}else if( c=='-' || (c>='0' && c<='9') ){ }else if( c=='-' || (c>='0' && c<='9') ){
@ -731,7 +739,7 @@ static int jsonParse(
i = jsonParseValue(pParse, 0); i = jsonParseValue(pParse, 0);
if( pParse->oom ) i = -1; if( pParse->oom ) i = -1;
if( i>0 ){ if( i>0 ){
while( isspace(zJson[i]) ) i++; while( safe_isspace(zJson[i]) ) i++;
if( zJson[i] ) i = -1; if( zJson[i] ) i = -1;
} }
if( i<=0 ){ if( i<=0 ){
@ -862,11 +870,11 @@ static JsonNode *jsonLookupStep(
} }
return pNode; return pNode;
} }
}else if( zPath[0]=='[' && isdigit(zPath[1]) ){ }else if( zPath[0]=='[' && safe_isdigit(zPath[1]) ){
if( pRoot->eType!=JSON_ARRAY ) return 0; if( pRoot->eType!=JSON_ARRAY ) return 0;
i = 0; i = 0;
zPath++; zPath++;
while( isdigit(zPath[0]) ){ while( safe_isdigit(zPath[0]) ){
i = i*10 + zPath[0] - '0'; i = i*10 + zPath[0] - '0';
zPath++; zPath++;
} }

View File

@ -1,5 +1,5 @@
C Fix\sa\scrash\sin\sFTS5\scaused\sby\sspecifying\sNULL\sas\sthe\srhs\sof\sa\sMATCH\soperator. C Avoid\spassing\s(signed\schar)\svalues\sdirectly\sto\sisspace(),\sisalnum()\sor\sisdigit()\sin\sjson1.c.\sCast\sthe\svalue\sto\s(unsigned\schar)\sfirst.
D 2015-09-17T09:48:01.737 D 2015-09-17T17:21:09.569
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in f85066ce844a28b671aaeeff320921cd0ce36239 F Makefile.in f85066ce844a28b671aaeeff320921cd0ce36239
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -195,7 +195,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
F ext/misc/fuzzer.c 4c84635c71c26cfa7c2e5848cf49fe2d2cfcd767 F ext/misc/fuzzer.c 4c84635c71c26cfa7c2e5848cf49fe2d2cfcd767
F ext/misc/ieee754.c b0362167289170627659e84173f5d2e8fee8566e F ext/misc/ieee754.c b0362167289170627659e84173f5d2e8fee8566e
F ext/misc/json1.c f35d00fbd79a7e23af18d7630a2fcf22dce3692b F ext/misc/json1.c 4b1048a7f4f2989d27c451cef80e06d77d69921e
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
@ -816,7 +816,7 @@ F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
F test/json101.test e20d2421c531db32fad59c5e06e80af0b1b002c8 F test/json101.test e20d2421c531db32fad59c5e06e80af0b1b002c8
F test/json102.test 4e1403cb06481ab160cf471c3c139820498e0563 F test/json102.test b6282433ac49c57ab00ed55e8b9fd5317e699b3d
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
@ -1387,7 +1387,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 0f3de2d337a3113dbd0765aa5545bb586b780121 P e8ed62f82e8acc40b818bf86fafe3d480687514e
R fedcc551e6201e5eaa9f1e4cebc37090 R b33f39da72f7f6726ef8bfa6df3023ed
U dan U dan
Z 3e310c615687f1a54e1d7e8496a4b4b6 Z 7dc427d84823f016abf1cb61f1158516

View File

@ -1 +1 @@
e8ed62f82e8acc40b818bf86fafe3d480687514e 6713e35b8a8c997aa2717e86ce6dcd63bb993477

View File

@ -278,4 +278,11 @@ do_execsql_test json102-1132 {
} {123} } {123}
} ;# end ifcapable vtab } ;# end ifcapable vtab
#-------------------------------------------------------------------------
# Test that json_valid() correctly identifies non-ascii range
# characters as non-whitespace.
#
do_execsql_test json102-1201 { SELECT json_valid(char(32) || '"xyz"') } 1
do_execsql_test json102-1202 { SELECT json_valid(char(200) || '"xyz"') } 0
finish_test finish_test