1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-09 14:21:03 +03:00

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
This commit is contained in:
drh
2023-12-02 18:04:27 +00:00
parent 05db513435
commit a11aaff05a
3 changed files with 19 additions and 11 deletions

View File

@@ -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;