aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <>2024-01-22 14:16:10 +0000
committerdrh <>2024-01-22 14:16:10 +0000
commit41fb2eed07d109c5bf452d443562ec154dc3b78a (patch)
tree3292ea6379ad79f71c7018e1eaa609864563d62b /src
parentb4b7088d5f48f159320d81497a47f4804dd12be7 (diff)
downloadsqlite-41fb2eed07d109c5bf452d443562ec154dc3b78a.tar.gz
sqlite-41fb2eed07d109c5bf452d443562ec154dc3b78a.zip
The -DSQLITE_JSON_BLOB_INPUT_BUG_COMPATIBLE compile-time option causes blob
inputs to JSON functions that are not JSONB to be processed as if they where text, immulating historical bugging behavior which some applications have come to rely upon. See [forum:/forumpost/012136abd5292b8d|forum thread 012136abd5292b8d] for discussion. FossilOrigin-Name: 65572223583d43e1d61ec029641f9d3ff340e68ecfba8342c8d1b0a91a680f2a
Diffstat (limited to 'src')
-rw-r--r--src/json.c73
1 files changed, 51 insertions, 22 deletions
diff --git a/src/json.c b/src/json.c
index d33692466..b9a88822e 100644
--- a/src/json.c
+++ b/src/json.c
@@ -3218,6 +3218,38 @@ jsonInsertIntoBlob_patherror:
}
/*
+** If pArg is a blob that seems like a JSONB blob, then initialize
+** p to point to that JSONB and return TRUE. If pArg does not seem like
+** a JSONB blob, then return FALSE;
+**
+** This routine is only called if it is already known that pArg is a
+** blob. The only open question is whether or not the blob appears
+** to be a JSONB blob.
+*/
+static int jsonArgIsJsonb(sqlite3_value *pArg, JsonParse *p){
+ u32 n, sz = 0;
+ p->aBlob = (u8*)sqlite3_value_blob(pArg);
+ p->nBlob = (u32)sqlite3_value_bytes(pArg);
+ if( p->nBlob==0 ){
+ p->aBlob = 0;
+ return 0;
+ }
+ if( NEVER(p->aBlob==0) ){
+ return 0;
+ }
+ if( (p->aBlob[0] & 0x0f)<=JSONB_OBJECT
+ && (n = jsonbPayloadSize(p, 0, &sz))>0
+ && sz+n==p->nBlob
+ && ((p->aBlob[0] & 0x0f)>JSONB_FALSE || sz==0)
+ ){
+ return 1;
+ }
+ p->aBlob = 0;
+ p->nBlob = 0;
+ return 0;
+}
+
+/*
** Generate a JsonParse object, containing valid JSONB in aBlob and nBlob,
** from the SQL function argument pArg. Return a pointer to the new
** JsonParse object.
@@ -3273,29 +3305,26 @@ rebuild_from_cache:
return p;
}
if( eType==SQLITE_BLOB ){
- u32 n, sz = 0;
- p->aBlob = (u8*)sqlite3_value_blob(pArg);
- p->nBlob = (u32)sqlite3_value_bytes(pArg);
- if( p->nBlob==0 ){
- goto json_pfa_malformed;
- }
- if( NEVER(p->aBlob==0) ){
- goto json_pfa_oom;
- }
- if( (p->aBlob[0] & 0x0f)>JSONB_OBJECT ){
- goto json_pfa_malformed;
- }
- n = jsonbPayloadSize(p, 0, &sz);
- if( n==0
- || sz+n!=p->nBlob
- || ((p->aBlob[0] & 0x0f)<=JSONB_FALSE && sz>0)
- ){
- goto json_pfa_malformed;
- }
- if( (flgs & JSON_EDITABLE)!=0 && jsonBlobMakeEditable(p, 0)==0 ){
- goto json_pfa_oom;
+ if( jsonArgIsJsonb(pArg,p) ){
+ if( (flgs & JSON_EDITABLE)!=0 && jsonBlobMakeEditable(p, 0)==0 ){
+ goto json_pfa_oom;
+ }
+ return p;
}
- return p;
+#if defined(SQLITE_JSON_BLOB_INPUT_BUG_COMPATIBLE)
+ /* If the input is a BLOB that is not JSONB, fall through into trying
+ ** to process that BLOB as if it where text. This goes against all
+ ** historical documentation about how the SQLite JSON functions are
+ ** suppose to work. Nevertheless, many SQLite implementations prior to
+ ** version 3.45.0 contained a bug such that they did behave this way
+ ** and some applications came to depend upon this buggy behavior. The
+ ** SQLITE_JSON_BLOB_INPUT_BUG_COMPATIBLE compile-time option provides
+ ** a mechanism for those applications to continue working even after
+ ** the bug was fixed. See
+ ** https://sqlite.org/forum/forumpost/012136abd5292b8d */
+#else
+ goto json_pfa_malformed;
+#endif
}
p->zJson = (char*)sqlite3_value_text(pArg);
p->nJson = sqlite3_value_bytes(pArg);