aboutsummaryrefslogtreecommitdiff
path: root/src/json.c
diff options
context:
space:
mode:
authordrh <>2023-12-02 18:04:27 +0000
committerdrh <>2023-12-02 18:04:27 +0000
commita11aaff05ae0f9b43f4b717e0b3158c1e36e1c10 (patch)
tree43ea0a2db3ff76c1972171a13b637fa3eb9903dc /src/json.c
parent05db513435d21909be60b7dcf48574fdc74b8308 (diff)
downloadsqlite-a11aaff05ae0f9b43f4b717e0b3158c1e36e1c10.tar.gz
sqlite-a11aaff05ae0f9b43f4b717e0b3158c1e36e1c10.zip
Take extra care to ensure that JSONB values that are in cache are actually
owned by the JSON subsystem, and that ownership of such values is not handed back to the bytecode engine. FossilOrigin-Name: 1304534001e9ef66c6b12752b69d790bfa3427cc803f87cc48ca22ae12df0fdf
Diffstat (limited to 'src/json.c')
-rw-r--r--src/json.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/json.c b/src/json.c
index cdc0d60c7..586371d9d 100644
--- a/src/json.c
+++ b/src/json.c
@@ -375,6 +375,7 @@ static int jsonCacheInsert(
memmove(p->a, &p->a[1], (JSON_CACHE_SIZE-1)*sizeof(p->a[0]));
p->nUsed = JSON_CACHE_SIZE-1;
}
+ assert( pParse->nBlobAlloc>0 );
pParse->eEdit = 0;
pParse->nJPRef++;
pParse->bReadOnly = 1;
@@ -731,7 +732,7 @@ static void jsonReturnString(
sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
SQLITE_TRANSIENT, SQLITE_UTF8);
}else if( jsonForceRCStr(p) ){
- if( pParse && pParse->bJsonIsRCStr==0 ){
+ if( pParse && pParse->bJsonIsRCStr==0 && pParse->nBlobAlloc>0 ){
int rc;
pParse->zJson = sqlite3RCStrRef(p->zBuf);
pParse->nJson = p->nUsed;
@@ -1751,6 +1752,8 @@ static void jsonReturnStringAsBlob(JsonString *pStr){
sqlite3_free(px.aBlob);
sqlite3_result_error_nomem(pStr->pCtx);
}else{
+ assert( px.nBlobAlloc>0 );
+ assert( !px.bReadOnly );
sqlite3_result_blob(pStr->pCtx, px.aBlob, px.nBlob, sqlite3_free);
}
}
@@ -2841,9 +2844,12 @@ static void jsonReturnParse(
}
flgs = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
if( flgs & JSON_BLOB ){
- sqlite3_result_blob(ctx, p->aBlob, p->nBlob,
- p->nBlobAlloc>0 ? SQLITE_DYNAMIC : SQLITE_TRANSIENT);
- p->nBlobAlloc = 0;
+ if( p->nBlobAlloc>0 && !p->bReadOnly ){
+ sqlite3_result_blob(ctx, p->aBlob, p->nBlob, SQLITE_DYNAMIC);
+ p->nBlobAlloc = 0;
+ }else{
+ sqlite3_result_blob(ctx, p->aBlob, p->nBlob, SQLITE_TRANSIENT);
+ }
}else{
JsonString s;
jsonStringInit(&s, ctx);
@@ -3063,6 +3069,8 @@ static void jsonbFunc(
if( jsonConvertTextToBlob(pParse, ctx) ){
sqlite3_result_error(ctx, "malformed JSON", -1);
}else{
+ assert( pParse->nBlobAlloc>0 );
+ assert( !pParse->bReadOnly );
sqlite3_result_blob(ctx, pParse->aBlob, pParse->nBlob, sqlite3_free);
pParse->aBlob = 0;
pParse->nBlob = 0;