From: drh <> Date: Tue, 29 Mar 2022 01:43:09 +0000 (+0000) Subject: Fix the sqlite3_result_xxxxx() routines so that they all check for and X-Git-Tag: version-3.39.0~278 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fb92e071861384455519a718706d217c4e91a7d6;p=thirdparty%2Fsqlite.git Fix the sqlite3_result_xxxxx() routines so that they all check for and perform any necessary text encoding conversions and check for oversize strings and BLOBs. Thus those checks can be done where they are most efficient and avoided in cases like OP_Function where they are more expensive. FossilOrigin-Name: d50b162b2f2e320af0889b931351f9443580465a933f6657fa98f437b6579277 --- diff --git a/manifest b/manifest index d6dc655417..c7638368d1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\ssize\sand\sperformance\soptimizations\sfor\ssqlite3VdbeMemSetStr(). -D 2022-03-28T18:34:40.795 +C Fix\sthe\ssqlite3_result_xxxxx()\sroutines\sso\sthat\sthey\sall\scheck\sfor\sand\nperform\sany\snecessary\stext\sencoding\sconversions\sand\scheck\sfor\soversize\nstrings\sand\sBLOBs.\s\sThus\sthose\schecks\scan\sbe\sdone\swhere\sthey\sare\smost\nefficient\sand\savoided\sin\scases\slike\sOP_Function\swhere\sthey\sare\smore\nexpensive. +D 2022-03-29T01:43:09.917 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,13 +624,13 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c b1830c6daf744473a732257652b6431ac18032f508a3e30ff3a1466fe5978559 +F src/vdbe.c af4a5e9d64dbcc484be1fa4609b655577f81ee2cd40b61e96bece6d43718ae91 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h 8dd91427155a38ec06e9ecbde07e33f21bc02e101625191e7613f883e379a363 -F src/vdbeapi.c bc3812dff7c9e6497c87ae86962818a51f66f8d7a873e7ec02a22aa115b84799 +F src/vdbeapi.c 299da88f2788ac50b83890bbcfcfbfd09f5863604ad66f6165010cd897d087b5 F src/vdbeaux.c 1de06d17a1af1bf5cc776e60afcc01c49438df90863fc4db0a0516060e7b959a F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd -F src/vdbemem.c dc02c6b8d51bcfc50f02266cb7003395d2989b72a9df6be561fcecdf16040784 +F src/vdbemem.c d6add1f60a255bd513b2b66a4139e810a8060bfe3d0639c34a0b80923d00ef35 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c @@ -1945,8 +1945,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 06928e745c7bcb26ec46a17989f30efe3536fd48a74c8a1cd423cc9ff6feccb5 -R e5b296feee8b6ff8861e4cf66944c654 +P 310a3e102d8eedf92ee63ffffb48621abfb1e2736b96bd2a676d63cca0f40598 +R 36f3f4bc3d4f57fe3c73eaa6653f4db1 U drh -Z 8d86ba5638b23b699bb683c424e71903 +Z faba0725b64437f0f9101d235cb21291 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 17903a1e91..ddcd1c1d29 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -310a3e102d8eedf92ee63ffffb48621abfb1e2736b96bd2a676d63cca0f40598 \ No newline at end of file +d50b162b2f2e320af0889b931351f9443580465a933f6657fa98f437b6579277 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index cf6137ab0a..ec227f884a 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -7378,9 +7378,6 @@ case OP_AggFinal: { } sqlite3VdbeChangeEncoding(pMem, encoding); UPDATE_MAX_BLOBSIZE(pMem); - if( sqlite3VdbeMemTooBig(pMem) ){ - goto too_big; - } break; } @@ -7919,9 +7916,6 @@ case OP_VColumn: { REGISTER_TRACE(pOp->p3, pDest); UPDATE_MAX_BLOBSIZE(pDest); - if( sqlite3VdbeMemTooBig(pDest) ){ - goto too_big; - } if( rc ) goto abort_due_to_error; break; } @@ -8214,11 +8208,10 @@ case OP_Function: { /* group */ if( rc ) goto abort_due_to_error; } - /* Copy the result of the function into register P3 */ - if( pOut->flags & (MEM_Str|MEM_Blob) ){ - sqlite3VdbeChangeEncoding(pOut, encoding); - if( sqlite3VdbeMemTooBig(pOut) ) goto too_big; - } + assert( (pOut->flags&MEM_Str)==0 + || pOut->enc==encoding + || db->mallocFailed ); + assert( !sqlite3VdbeMemTooBig(pOut) ); REGISTER_TRACE(pOp->p3, pOut); UPDATE_MAX_BLOBSIZE(pOut); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index af1e94487c..48487694b2 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -378,7 +378,8 @@ static void setResultStrOrError( u8 enc, /* Encoding of z. 0 for BLOBs */ void (*xDel)(void*) /* Destructor function */ ){ - int rc = sqlite3VdbeMemSetStr(pCtx->pOut, z, n, enc, xDel); + Mem *pOut = pCtx->pOut; + int rc = sqlite3VdbeMemSetStr(pOut, z, n, enc, xDel); if( rc ){ if( rc==SQLITE_TOOBIG ){ sqlite3_result_error_toobig(pCtx); @@ -388,6 +389,13 @@ static void setResultStrOrError( assert( rc==SQLITE_NOMEM ); sqlite3_result_error_nomem(pCtx); } + return; + } + if( pOut->enc!=ENC(pOut->db) ){ + sqlite3VdbeChangeEncoding(pOut, ENC(pOut->db)); + if( sqlite3VdbeMemTooBig(pOut) ){ + sqlite3_result_error_toobig(pCtx); + } } } static int invokeValueDestructor( @@ -531,17 +539,22 @@ void sqlite3_result_text16le( } #endif /* SQLITE_OMIT_UTF16 */ void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ + Mem *pOut = pCtx->pOut; assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - sqlite3VdbeMemCopy(pCtx->pOut, pValue); + sqlite3VdbeMemCopy(pOut, pValue); + sqlite3VdbeChangeEncoding(pOut, ENC(pOut->db)); + if( sqlite3VdbeMemTooBig(pOut) ){ + sqlite3_result_error_toobig(pCtx); + } } void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - sqlite3VdbeMemSetZeroBlob(pCtx->pOut, n); + sqlite3_result_zeroblob64(pCtx, n>0 ? n : 0); } int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){ Mem *pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){ + sqlite3_result_error_toobig(pCtx); return SQLITE_TOOBIG; } #ifndef SQLITE_OMIT_INCRBLOB @@ -557,8 +570,8 @@ void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode; #endif if( pCtx->pOut->flags & MEM_Null ){ - sqlite3VdbeMemSetStr(pCtx->pOut, sqlite3ErrStr(errCode), -1, - SQLITE_UTF8, SQLITE_STATIC); + setResultStrOrError(pCtx, sqlite3ErrStr(errCode), -1, SQLITE_UTF8, + SQLITE_STATIC); } } diff --git a/src/vdbemem.c b/src/vdbemem.c index 524280e0df..7a736fc21b 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -204,7 +204,11 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ assert( !sqlite3VdbeMemIsRowSet(pMem) ); assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE || desiredEnc==SQLITE_UTF16BE ); - if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){ + if( pMem->enc==desiredEnc ){ + return SQLITE_OK; + } + if( !(pMem->flags&MEM_Str) ){ + pMem->enc = desiredEnc; return SQLITE_OK; } assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); @@ -1152,12 +1156,7 @@ int sqlite3VdbeMemSetStr( flags= MEM_Str|MEM_Term; }else if( enc==0 ){ flags = MEM_Blob; -#ifdef SQLITE_ENABLE_SESSION - enc = pMem->db ? ENC(pMem->db) : SQLITE_UTF8; -#else - assert( pMem->db!=0 ); - enc = ENC(pMem->db); -#endif + enc = SQLITE_UTF8; }else{ flags = MEM_Str; } @@ -1205,10 +1204,7 @@ int sqlite3VdbeMemSetStr( pMem->enc = enc; #ifndef SQLITE_OMIT_UTF16 - if( enc>SQLITE_UTF8 - && (flags & MEM_Blob)==0 - && sqlite3VdbeMemHandleBom(pMem) - ){ + if( enc>SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){ return SQLITE_NOMEM_BKPT; } #endif