From: drh Date: Tue, 7 Oct 2014 23:02:24 +0000 (+0000) Subject: Make sure the sqlite3VdbeMemClearAndResize() routine is never called with a X-Git-Tag: version-3.8.7~39 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=722246e801299ea9042db1278ab6365384d72e22;p=thirdparty%2Fsqlite.git Make sure the sqlite3VdbeMemClearAndResize() routine is never called with a zero size parameter, since a size of zero could lead to either a memory leak or an assertion fault. FossilOrigin-Name: f672a380e2e52bede95ff11a533fd9f7d412d494 --- diff --git a/manifest b/manifest index 433a723055..8b6acbd4de 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\scorruptI.test\sscript\sso\sthat\sit\sworks\swith\nSQLITE_ENABLE_OVERSIZE_CELL_CHECK\sand\swith\sSQLITE_DEFAULT_AUTOVACUUM=1. -D 2014-10-07T20:09:27.561 +C Make\ssure\sthe\ssqlite3VdbeMemClearAndResize()\sroutine\sis\snever\scalled\swith\sa\nzero\ssize\sparameter,\ssince\sa\ssize\sof\szero\scould\slead\sto\seither\sa\smemory\sleak\nor\san\sassertion\sfault. +D 2014-10-07T23:02:24.724 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -289,13 +289,13 @@ F src/update.c 729f6f18fc27740591d085e1172cebe311144bf0 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8 F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a -F src/vdbe.c 93eeb6f9c3a3084133225a196f220454d71cca10 +F src/vdbe.c e6c964101382d6fb144853b1d5b288158a9aba0e F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327 F src/vdbeInt.h 0b97a3190f8fbf460655985a9183019f5a702754 F src/vdbeapi.c 37a6c6ae284a97bcace365f2f0a225680c0499d9 F src/vdbeaux.c 5b687d7b5beaaa5b97189edf25cf08c311834933 F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 -F src/vdbemem.c ee0c60af8c0f5535c6a06c49a624d87cf70b0573 +F src/vdbemem.c 481327f50d9da330053aa7456702ce46d0a4e70f F src/vdbesort.c 5c1bacf90578d22b630fbf6ed98ccf60d83435ef F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010 F src/vtab.c 019dbfd0406a7447c990e1f7bd1dfcdb8895697f @@ -1202,7 +1202,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 13c962b33df411a0d9ead0bb1969596faa286f79 -R bc98a778a72f51d6ea08f3f2bdc76392 +P e405b9e4a9ef322d84b20e902234b4f6aa196b1b +R 59a3e15d0b7c925a5c413304ec5e314b U drh -Z 156ceab5010f208eb433cfa9f4253059 +Z 1de6834c7b78df261ad24af6ce5dedbe diff --git a/manifest.uuid b/manifest.uuid index d79d2fd138..169d9b9887 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e405b9e4a9ef322d84b20e902234b4f6aa196b1b \ No newline at end of file +f672a380e2e52bede95ff11a533fd9f7d412d494 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 34eb1d42c5..18e1cd83a9 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4333,7 +4333,8 @@ case OP_RowData: { goto too_big; } } - if( sqlite3VdbeMemClearAndResize(pOut, n) ){ + testcase( n==0 ); + if( sqlite3VdbeMemClearAndResize(pOut, MAX(n,32)) ){ goto no_mem; } pOut->n = n; diff --git a/src/vdbemem.c b/src/vdbemem.c index a4caf51759..0c62db0720 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -31,7 +31,10 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){ */ assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 ); - /* MEM_Dyn may only be set if Mem.szMalloc==0 */ + /* MEM_Dyn may only be set if Mem.szMalloc==0. In this way we + ** ensure that if Mem.szMalloc>0 then it is safe to do + ** Mem.z = Mem.zMalloc without having to check Mem.flags&MEM_Dyn. + ** That saves a few cycles in inner loops. */ assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 ); /* Cannot be both MEM_Int and MEM_Real at the same time */ @@ -167,7 +170,8 @@ SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ ** if unable to complete the resizing. */ int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ - assert( szNew>=0 ); + assert( szNew>0 ); + assert( (pMem->flags & MEM_Dyn)==0 || pMem->szMalloc==0 ); if( pMem->szMallociLimit ){ return SQLITE_TOOBIG; } - if( sqlite3VdbeMemClearAndResize(pMem, nAlloc) ){ + testcase( nAlloc==0 ); + testcase( nAlloc==31 ); + testcase( nAlloc==32 ); + if( sqlite3VdbeMemClearAndResize(pMem, MAX(nAlloc,32)) ){ return SQLITE_NOMEM; } memcpy(pMem->z, z, nAlloc);