diff options
author | drh <> | 2023-12-02 18:04:27 +0000 |
---|---|---|
committer | drh <> | 2023-12-02 18:04:27 +0000 |
commit | a11aaff05ae0f9b43f4b717e0b3158c1e36e1c10 (patch) | |
tree | 43ea0a2db3ff76c1972171a13b637fa3eb9903dc /src/json.c | |
parent | 05db513435d21909be60b7dcf48574fdc74b8308 (diff) | |
download | sqlite-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.c | 16 |
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; |