diff options
author | drh <> | 2023-10-07 19:05:10 +0000 |
---|---|---|
committer | drh <> | 2023-10-07 19:05:10 +0000 |
commit | f26833d7837932c7a3ecc6522e439947e34074e0 (patch) | |
tree | 30e7756ac50c2fdfd20f36a4225cce8cb3c0cef3 /src | |
parent | 1244b6cbf663132e6f3d8c285eef0162c6fca397 (diff) | |
download | sqlite-f26833d7837932c7a3ecc6522e439947e34074e0.tar.gz sqlite-f26833d7837932c7a3ecc6522e439947e34074e0.zip |
Fix the jsonbChangePayloadSize() routine so that it shifts the payload in order
to always render the most compact encoding of the payload size. This is
necessary as sometimes (as discovered by dbsqlfuzz) the payload size can
grow significantly due to json_insert() or json_replace().
FossilOrigin-Name: 8d6d04ca975ec55c419d40d8463c433b0db698c9fb4812ab9f16d4ee5bee460e
Diffstat (limited to 'src')
-rw-r--r-- | src/json.c | 49 |
1 files changed, 40 insertions, 9 deletions
diff --git a/src/json.c b/src/json.c index fac05a077..6f31214f5 100644 --- a/src/json.c +++ b/src/json.c @@ -2607,24 +2607,55 @@ static void jsonBlobChangePayloadSize( ){ u8 *a; u8 szType; + u8 nExtra; + u8 nNeeded; + i8 delta; if( pParse->oom ) return; a = &pParse->aBlob[i]; szType = a[0]>>4; if( szType<=11 ){ - assert( szPayload<=11 ); + nExtra = 0; + }else if( szType==12 ){ + nExtra = 1; + }else if( szType==13 ){ + nExtra = 2; + }else{ + nExtra = 4; + } + if( szPayload<=11 ){ + nNeeded = 0; + }else if( szPayload<=0xff ){ + nNeeded = 1; + }else if( szPayload<=0xffff ){ + nNeeded = 2; + }else{ + nNeeded = 4; + } + delta = nNeeded - nExtra; + if( delta ){ + u32 newSize = pParse->nBlob + delta; + if( delta>0 ){ + if( newSize>pParse->nBlobAlloc && jsonBlobExpand(pParse, newSize) ){ + return; /* OOM error. Error state recorded in pParse->oom. */ + } + a = &pParse->aBlob[i]; + memmove(&a[1+delta], &a[1], pParse->nBlob - (i+1)); + }else{ + memmove(&a[1], &a[1-delta], pParse->nBlob - (i+1-delta)); + } + pParse->nBlob = newSize; + } + if( nNeeded==0 ){ a[0] = (a[0] & 0x0f) | (szPayload<<4); - }else if( szType==0xc ){ - assert( szPayload<=0xff ); - assert( i+1<pParse->nBlob ); + }else if( nNeeded==1 ){ + a[0] = (a[0] & 0x0f) | 0xc0; a[1] = szPayload & 0xff; - }else if( szType==0xd ){ - assert( szPayload<=0xffff ); - assert( i+2<pParse->nBlob ); + }else if( nNeeded==2 ){ + a[0] = (a[0] & 0x0f) | 0xd0; a[1] = (szPayload >> 8) & 0xff; a[2] = szPayload & 0xff; }else{ - assert( szType==0xe ); - assert( i+4<pParse->nBlob ); + a[0] = (a[0] & 0x0f) | 0xe0; a[1] = (szPayload >> 24) & 0xff; a[2] = (szPayload >> 16) & 0xff; a[3] = (szPayload >> 8) & 0xff; |