From f51d1bd6653be0a41843d4a5227ba637e5ab9f1a Mon Sep 17 00:00:00 2001 From: danielk1977 Date: Fri, 31 Jul 2009 06:14:51 +0000 Subject: [PATCH] Fix a bug in where.c that could cause SQLite to write to freed memory while compiling a query with many terms in the WHERE clause. (CVS 6952) FossilOrigin-Name: 8161af840e8fd2b06457e75023f934e1b8fe5fd6 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 3 ++- test/where8.test | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 56 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 6207dc61cf..4b664dab8d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\stest\sto\smallocI.test\sto\sshow\sthat\sa\sshared\slock\sis\scorrectly\sreleased\sif\san\sOOM\scondition\soccurs\swhile\sparsing\sa\sdatabase\sschema.\s(CVS\s6951) -D 2009-07-29T06:04:57 +C Fix\sa\sbug\sin\swhere.c\sthat\scould\scause\sSQLite\sto\swrite\sto\sfreed\smemory\swhile\scompiling\sa\squery\swith\smany\sterms\sin\sthe\sWHERE\sclause.\s(CVS\s6952) +D 2009-07-31T06:14:52 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in df9359da7a726ccb67a45db905c5447d5c00c6ef F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -213,7 +213,7 @@ F src/vdbeblob.c a3f3e0e877fc64ea50165eec2855f5ada4477611 F src/vdbemem.c bfc25f9ef4fa914b473303566459552bdb2e008a F src/vtab.c b19c4e96dcf2b89b5b2ba48e8ef624e654a59b2c F src/walker.c 1edca756275f158b80f20eb6f104c8d3fcc96a04 -F src/where.c de6ab601ee6f7a886f1380b63122883ef570a88f +F src/where.c 7e696d69a6d1b0fa277da2801ae4126dd4db0f8c F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 14165b3e32715b700b5f0cbf8f6e3833dda0be45 @@ -710,7 +710,7 @@ F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2 F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2 F test/where6.test 42c4373595f4409d9c6a9987b4a60000ad664faf F test/where7.test b6e84b472a024e45c6dbdadc52bbcab3fcc8d0e1 -F test/where8.test 4839a0a1447e178a9a0725c5136fb963445e7708 +F test/where8.test fb2ccd7f1fa33287fef25b6bad6849c868a6e331 F test/where8m.test da346596e19d54f0aba35ebade032a7c47d79739 F test/where9.test be19e1a92f80985c1a121b4678bf7d2123eaa623 F test/whereA.test 1d1674254614147c866ab9b59af6582f454a858c @@ -740,7 +740,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746 -P 4571aa9e9142db465ae8250b0adf27e0a094331a -R dcea50c6f35f0aec2ba3cb61a9fe65cb +P 5a82620efa1298530760e69e4e34d446a30233b8 +R 5171f50e963fce31c959e66efb3a8d0a U danielk1977 -Z c8de658c5b21527a701e58d71776ac0b +Z 77225468b9c3e046f4f8c47188f8bd03 diff --git a/manifest.uuid b/manifest.uuid index 71e5356d94..eb2f071459 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5a82620efa1298530760e69e4e34d446a30233b8 \ No newline at end of file +8161af840e8fd2b06457e75023f934e1b8fe5fd6 \ No newline at end of file diff --git a/src/where.c b/src/where.c index ca31e45188..1921ee3a34 100644 --- a/src/where.c +++ b/src/where.c @@ -16,7 +16,7 @@ ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** -** $Id: where.c,v 1.410 2009/07/28 08:43:09 shane Exp $ +** $Id: where.c,v 1.411 2009/07/31 06:14:52 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -1176,6 +1176,7 @@ static void exprAnalyze( else if( pExpr->op==TK_OR ){ assert( pWC->op==TK_AND ); exprAnalyzeOrTerm(pSrc, pWC, idxTerm); + pTerm = &pWC->a[idxTerm]; } #endif /* SQLITE_OMIT_OR_OPTIMIZATION */ diff --git a/test/where8.test b/test/where8.test index 9167bad193..623d382459 100644 --- a/test/where8.test +++ b/test/where8.test @@ -12,7 +12,7 @@ # is testing of where.c. More specifically, the focus is the optimization # of WHERE clauses that feature the OR operator. # -# $Id: where8.test,v 1.8 2009/06/07 23:45:11 drh Exp $ +# $Id: where8.test,v 1.9 2009/07/31 06:14:52 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -653,9 +653,53 @@ foreach idxsql { } incr A } - catch {unset results} catch {unset A} catch {unset B} +# At one point the following tests provoked an invalid write error (writing +# to memory that had already been freed). It was not possible to demonstrate +# that this bug could cause a query to return bad data. +# +do_test where8-5.1 { + db close + sqlite3 db test.db + sqlite3_db_config_lookaside db 0 0 0 + execsql { + CREATE TABLE tA( + a, b, c, d, e, f, g, h, + i, j, k, l, m, n, o, p + ); + } + execsql { + SELECT * FROM tA WHERE + a=1 AND b=2 AND c=3 AND d=4 AND e=5 AND f=6 AND g=7 AND h=8 AND + i=1 AND j=2 AND k=3 AND l=4 AND m=5 AND n=6 AND o=7 AND + (p = 1 OR p = 2 OR p = 3) + } +} {} +do_test where8-5.2 { + execsql { + SELECT * FROM tA WHERE + a=1 AND b=2 AND c=3 AND d=4 AND e=5 AND f=6 AND g=7 AND h=8 AND + i=1 AND j=2 AND k=3 AND l=4 AND m=5 AND + (p = 1 OR p = 2 OR p = 3) AND n=6 AND o=7 + } +} {} +do_test where8-5.3 { + execsql { + INSERT INTO tA VALUES(1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8); + CREATE UNIQUE INDEX tAI ON tA(p); + CREATE TABLE tB(x); + INSERT INTO tB VALUES('x'); + } + execsql { + SELECT a, x FROM tA LEFT JOIN tB ON ( + a=1 AND b=2 AND c=3 AND d=4 AND e=5 AND f=6 AND g=7 AND h=8 AND + i=1 AND j=2 AND k=3 AND l=4 AND m=5 AND n=6 AND o=7 AND + (p = 1 OR p = 2 OR p = 3) + ) + } +} {1 {}} + finish_test