aboutsummaryrefslogtreecommitdiff
path: root/src/json.c
diff options
context:
space:
mode:
authordrh <>2023-12-07 12:55:39 +0000
committerdrh <>2023-12-07 12:55:39 +0000
commit5b6b7034615f009923fe46ee6f1fcebf23c66fdd (patch)
treece3e0a463326b693489b0f317f5449690e342d7e /src/json.c
parent00f3ac5544db5fcb86ae09b791b2d43945c31aac (diff)
downloadsqlite-5b6b7034615f009923fe46ee6f1fcebf23c66fdd.tar.gz
sqlite-5b6b7034615f009923fe46ee6f1fcebf23c66fdd.zip
Improved detection of corrupt JSONB in the jsonReturnFromBlob() function.
FossilOrigin-Name: b014736c1f80ccc46fb4b24ac04310a6ce5cb5b6653665efff366cb3bc742257
Diffstat (limited to 'src/json.c')
-rw-r--r--src/json.c43
1 files changed, 31 insertions, 12 deletions
diff --git a/src/json.c b/src/json.c
index 46d7a3fa8..850e2241e 100644
--- a/src/json.c
+++ b/src/json.c
@@ -2618,14 +2618,17 @@ static void jsonReturnFromBlob(
}
switch( pParse->aBlob[i] & 0x0f ){
case JSONB_NULL: {
+ if( sz ) goto returnfromblob_malformed;
sqlite3_result_null(pCtx);
break;
}
case JSONB_TRUE: {
+ if( sz ) goto returnfromblob_malformed;
sqlite3_result_int(pCtx, 1);
break;
}
case JSONB_FALSE: {
+ if( sz ) goto returnfromblob_malformed;
sqlite3_result_int(pCtx, 0);
break;
}
@@ -2634,16 +2637,25 @@ static void jsonReturnFromBlob(
sqlite3_int64 iRes = 0;
char *z;
int bNeg = 0;
- char x = (char)pParse->aBlob[i+n];
- if( x=='-' && ALWAYS(sz>0) ){ n++; sz--; bNeg = 1; }
+ char x;
+ if( sz==0 ) goto returnfromblob_malformed;
+ x = (char)pParse->aBlob[i+n];
+ if( x=='-' ){
+ if( sz<2 ) goto returnfromblob_malformed;
+ n++;
+ sz--;
+ bNeg = 1;
+ }
z = sqlite3DbStrNDup(db, (const char*)&pParse->aBlob[i+n], (int)sz);
- if( z==0 ) return;
+ if( z==0 ) goto returnfromblob_oom;
rc = sqlite3DecOrHexToI64(z, &iRes);
sqlite3DbFree(db, z);
- if( rc<=1 ){
+ if( rc==0 ){
sqlite3_result_int64(pCtx, bNeg ? -iRes : iRes);
}else if( rc==3 && bNeg ){
sqlite3_result_int64(pCtx, SMALLEST_INT64);
+ }else if( rc==1 ){
+ goto returnfromblob_malformed;
}else{
if( bNeg ){ n--; sz++; }
goto to_double;
@@ -2654,11 +2666,13 @@ static void jsonReturnFromBlob(
case JSONB_FLOAT: {
double r;
char *z;
+ if( sz==0 ) goto returnfromblob_malformed;
to_double:
z = sqlite3DbStrNDup(db, (const char*)&pParse->aBlob[i+n], (int)sz);
- if( z==0 ) return;
- sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
+ if( z==0 ) goto returnfromblob_oom;
+ rc = sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
sqlite3DbFree(db, z);
+ if( rc<=0 ) goto returnfromblob_malformed;
sqlite3_result_double(pCtx, r);
break;
}
@@ -2677,10 +2691,7 @@ static void jsonReturnFromBlob(
u32 nOut = sz;
z = (const char*)&pParse->aBlob[i+n];
zOut = sqlite3_malloc( nOut+1 );
- if( zOut==0 ){
- sqlite3_result_error_nomem(pCtx);
- break;
- }
+ if( zOut==0 ) goto returnfromblob_oom;
for(iIn=iOut=0; iIn<sz; iIn++){
char c = z[iIn];
if( c=='\\' ){
@@ -2721,10 +2732,18 @@ static void jsonReturnFromBlob(
break;
}
default: {
- sqlite3_result_error(pCtx, "malformed JSON", -1);
- break;
+ goto returnfromblob_malformed;
}
}
+ return;
+
+returnfromblob_oom:
+ sqlite3_result_error_nomem(pCtx);
+ return;
+
+returnfromblob_malformed:
+ sqlite3_result_error(pCtx, "malformed JSON", -1);
+ return;
}
/*