After calling realloc() on an array to resize it, be sure not to use pointers

into the old array.  Ticket #1376. (CVS 2617)

FossilOrigin-Name: 9f9a257123274779150cbc290b9f86a09b3b2c03
This commit is contained in:
drh 2005-08-24 03:52:18 +00:00
parent 7681618c18
commit 9eb2028fbc
4 changed files with 85 additions and 40 deletions

View File

@ -1,5 +1,5 @@
C Allow\sfloating\spoint\sliterals\sto\sbeing\sor\send\swith\sa\sdecimal\spoint.\nTicket\s#1371.\s(CVS\s2616)
D 2005-08-23T11:31:26
C After\scalling\srealloc()\son\san\sarray\sto\sresize\sit,\sbe\ssure\snot\sto\suse\spointers\ninto\sthe\sold\sarray.\s\sTicket\s#1376.\s(CVS\s2617)
D 2005-08-24T03:52:19
F Makefile.in b109ddb46a5550d0732dcd6caca01c123f6d5cdd
F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@ -87,7 +87,7 @@ F src/vdbeapi.c 7790e9f8da2dde29510a196d1e41ff53da7eb8a8
F src/vdbeaux.c 874624698fad54a59c6a0bcccea9d5aaa8655ab6
F src/vdbefifo.c b8805850afe13b43f1de78d58088cb5d66f88e1e
F src/vdbemem.c 4732fd4d1a75dc38549493d7f9a81d02bf7c59b5
F src/where.c 8392d521f901f83f95bf32e52255a0efe98677af
F src/where.c 485041aa51fb33f43b346e018f7c01422847f364
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
F test/all.test 7f0988442ab811dfa41793b5b550f5828ce316f3
F test/alter.test 9d6837a3d946b73df692b7cef2a7644d2e2f6bc6
@ -233,7 +233,7 @@ F test/vacuum.test 5d4857ae2afc9c20d0edb8acc58bdc8d630126a9
F test/vacuum2.test 5d77e98c458bcdbeecc6327de5107179ba1aa095
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
F test/view.test ce0f0ad39fa4a3572acffcf1e634850ee151aae0
F test/where.test b6ab0f64adc5fbb4259f284b19da6cd9aeadc711
F test/where.test 8fcdf3e787d16d3be2d96a94d30273a98c9bbed1
F test/where2.test 503e2e2b6abe14c5c10222e72d08ef84c1bf1ffb
F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
F tool/lemon.c c88936c67f6411608db8fa4254d254f509fa40f6
@ -297,7 +297,7 @@ F www/tclsqlite.tcl 3df553505b6efcad08f91e9b975deb2e6c9bb955
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
P 5cada745ac9bf18a65d21705a398b2bb8bd1aaa2
R 23e7da0d5916b11561047a69d2280244
P a715e7001247e84e0982335570593f0802774635
R 6ff5e242d53c76146c4cacd607c45e12
U drh
Z 133248954b96d2da66ef949953aea49b
Z 76532fdd67839f2a5a8be585f7028686

View File

@ -1 +1 @@
a715e7001247e84e0982335570593f0802774635
9f9a257123274779150cbc290b9f86a09b3b2c03

View File

@ -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.164 2005/08/19 19:14:13 drh Exp $
** $Id: where.c,v 1.165 2005/08/24 03:52:19 drh Exp $
*/
#include "sqliteInt.h"
@ -80,7 +80,6 @@ typedef struct WhereClause WhereClause;
typedef struct WhereTerm WhereTerm;
struct WhereTerm {
Expr *pExpr; /* Pointer to the subexpression */
u16 idx; /* Index of this term in pWC->a[] */
i16 iParent; /* Disable pWC->a[iParent] when this term disabled */
i16 leftCursor; /* Cursor number of X in "X <op> <expr>" */
i16 leftColumn; /* Column number of X in "X <op> <expr>" */
@ -203,9 +202,15 @@ static void whereClauseClear(WhereClause *pWC){
/*
** Add a new entries to the WhereClause structure. Increase the allocated
** space as necessary.
**
** WARNING: This routine might reallocate the space used to store
** WhereTerms. All pointers to WhereTerms should be invalided after
** calling this routine. Such pointers may be reinitialized by referencing
** the pWC->a[] array.
*/
static WhereTerm *whereClauseInsert(WhereClause *pWC, Expr *p, int flags){
static int whereClauseInsert(WhereClause *pWC, Expr *p, int flags){
WhereTerm *pTerm;
int idx;
if( pWC->nTerm>=pWC->nSlot ){
WhereTerm *pOld = pWC->a;
pWC->a = sqliteMalloc( sizeof(pWC->a[0])*pWC->nSlot*2 );
@ -216,14 +221,13 @@ static WhereTerm *whereClauseInsert(WhereClause *pWC, Expr *p, int flags){
}
pWC->nSlot *= 2;
}
pTerm = &pWC->a[pWC->nTerm];
pTerm->idx = pWC->nTerm;
pTerm = &pWC->a[idx = pWC->nTerm];
pWC->nTerm++;
pTerm->pExpr = p;
pTerm->flags = flags;
pTerm->pWC = pWC;
pTerm->iParent = -1;
return pTerm;
return idx;
}
/*
@ -438,7 +442,7 @@ static WhereTerm *findTerm(
}
/* Forward reference */
static void exprAnalyze(SrcList*, ExprMaskSet*, WhereTerm*);
static void exprAnalyze(SrcList*, ExprMaskSet*, WhereClause*, int);
/*
** Call exprAnalyze on all terms in a WHERE clause.
@ -450,10 +454,9 @@ static void exprAnalyzeAll(
ExprMaskSet *pMaskSet, /* table masks */
WhereClause *pWC /* the WHERE clause to be analyzed */
){
WhereTerm *pTerm;
int i;
for(i=pWC->nTerm-1, pTerm=pWC->a; i>=0; i--, pTerm++){
exprAnalyze(pTabList, pMaskSet, pTerm);
for(i=pWC->nTerm-1; i>=0; i--){
exprAnalyze(pTabList, pMaskSet, pWC, i);
}
}
@ -516,8 +519,10 @@ static int isLikeOrGlob(
static void exprAnalyze(
SrcList *pSrc, /* the FROM clause */
ExprMaskSet *pMaskSet, /* table masks */
WhereTerm *pTerm /* the WHERE clause term to be analyzed */
WhereClause *pWC, /* the WHERE clause */
int idxTerm /* Index of the term to be analyzed */
){
WhereTerm *pTerm = &pWC->a[idxTerm];
Expr *pExpr = pTerm->pExpr;
Bitmask prereqLeft;
Bitmask prereqAll;
@ -545,10 +550,13 @@ static void exprAnalyze(
WhereTerm *pNew;
Expr *pDup;
if( pTerm->leftCursor>=0 ){
int idxNew;
pDup = sqlite3ExprDup(pExpr);
pNew = whereClauseInsert(pTerm->pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
if( pNew==0 ) return;
pNew->iParent = pTerm->idx;
idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
if( idxNew==0 ) return;
pNew = &pWC->a[idxNew];
pNew->iParent = idxTerm;
pTerm = &pWC->a[idxTerm];
pTerm->nChild = 1;
pTerm->flags |= TERM_COPIED;
}else{
@ -577,13 +585,13 @@ static void exprAnalyze(
assert( pList->nExpr==2 );
for(i=0; i<2; i++){
Expr *pNewExpr;
WhereTerm *pNewTerm;
int idxNew;
pNewExpr = sqlite3Expr(ops[i], sqlite3ExprDup(pExpr->pLeft),
sqlite3ExprDup(pList->a[i].pExpr), 0);
pNewTerm = whereClauseInsert(pTerm->pWC, pNewExpr,
TERM_VIRTUAL|TERM_DYNAMIC);
exprAnalyze(pSrc, pMaskSet, pNewTerm);
pNewTerm->iParent = pTerm->idx;
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
exprAnalyze(pSrc, pMaskSet, pWC, idxNew);
pTerm = &pWC->a[idxTerm];
pWC->a[idxNew].iParent = idxTerm;
}
pTerm->nChild = 2;
}
@ -601,7 +609,7 @@ static void exprAnalyze(
WhereTerm *pOrTerm;
assert( (pTerm->flags & TERM_DYNAMIC)==0 );
whereClauseInit(&sOr, pTerm->pWC->pParse);
whereClauseInit(&sOr, pWC->pParse);
whereSplit(&sOr, pExpr, TK_OR);
exprAnalyzeAll(pSrc, pMaskSet, &sOr);
assert( sOr.nTerm>0 );
@ -642,7 +650,8 @@ static void exprAnalyze(
if( pNew ) pNew->pList = pList;
pTerm->pExpr = pNew;
pTerm->flags |= TERM_DYNAMIC;
exprAnalyze(pSrc, pMaskSet, pTerm);
exprAnalyze(pSrc, pMaskSet, pWC, idxTerm);
pTerm = &pWC->a[idxTerm];
}
or_not_possible:
whereClauseClear(&sOr);
@ -653,11 +662,12 @@ or_not_possible:
/* Add constraints to reduce the search space on a LIKE or GLOB
** operator.
*/
if( isLikeOrGlob(pTerm->pWC->pParse->db, pExpr, &nPattern, &isComplete) ){
if( isLikeOrGlob(pWC->pParse->db, pExpr, &nPattern, &isComplete) ){
Expr *pLeft, *pRight;
Expr *pStr1, *pStr2;
Expr *pNewExpr1, *pNewExpr2;
WhereTerm *pNewTerm1, *pNewTerm2;
int idxNew1, idxNew2;
pLeft = pExpr->pList->a[1].pExpr;
pRight = pExpr->pList->a[0].pExpr;
pStr1 = sqlite3Expr(TK_STRING, 0, 0, 0);
@ -671,16 +681,15 @@ or_not_possible:
++*(u8*)&pStr2->token.z[nPattern-1];
}
pNewExpr1 = sqlite3Expr(TK_GE, sqlite3ExprDup(pLeft), pStr1, 0);
pNewTerm1 = whereClauseInsert(pTerm->pWC, pNewExpr1,
TERM_VIRTUAL|TERM_DYNAMIC);
exprAnalyze(pSrc, pMaskSet, pNewTerm1);
idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
exprAnalyze(pSrc, pMaskSet, pWC, idxNew1);
pNewExpr2 = sqlite3Expr(TK_LT, sqlite3ExprDup(pLeft), pStr2, 0);
pNewTerm2 = whereClauseInsert(pTerm->pWC, pNewExpr2,
TERM_VIRTUAL|TERM_DYNAMIC);
exprAnalyze(pSrc, pMaskSet, pNewTerm2);
idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
exprAnalyze(pSrc, pMaskSet, pWC, idxNew2);
pTerm = &pWC->a[idxTerm];
if( isComplete ){
pNewTerm2->iParent = pTerm->idx;
pNewTerm1->iParent = pTerm->idx;
pWC->a[idxNew1].iParent = idxTerm;
pWC->a[idxNew2].iParent = idxTerm;
pTerm->nChild = 2;
}
}

View File

@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The
# focus of this file is testing the use of indices in WHERE clases.
#
# $Id: where.test,v 1.32 2005/07/28 16:51:51 drh Exp $
# $Id: where.test,v 1.33 2005/08/24 03:52:19 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@ -230,6 +230,7 @@ do_test where-1.41 {
# Do the same kind of thing except use a join as the data source.
#
do_test where-2.1 {
btree_breakpoint
count {
SELECT w, p FROM t2, t1
WHERE x=q AND y=s AND r=8977
@ -868,6 +869,41 @@ do_test where-10.4 {
}
} {50}
# Ticket #1376. The query below was causing a segfault.
# The problem was the age-old error of calling realloc() on an
# array while there are still pointers to individual elements of
# that array.
#
do_test where-11.1 {
btree_breakpoint
execsql {
CREATE TABLE t99(Dte INT, X INT);
DELETE FROM t99 WHERE (Dte = 2451337) OR (Dte = 2451339) OR
(Dte BETWEEN 2451345 AND 2451347) OR (Dte = 2451351) OR
(Dte BETWEEN 2451355 AND 2451356) OR (Dte = 2451358) OR
(Dte = 2451362) OR (Dte = 2451365) OR (Dte = 2451367) OR
(Dte BETWEEN 2451372 AND 2451376) OR (Dte BETWEEN 2451382 AND 2451384) OR
(Dte = 2451387) OR (Dte BETWEEN 2451389 AND 2451391) OR
(Dte BETWEEN 2451393 AND 2451395) OR (Dte = 2451400) OR
(Dte = 2451402) OR (Dte = 2451404) OR (Dte BETWEEN 2451416 AND 2451418) OR
(Dte = 2451422) OR (Dte = 2451426) OR (Dte BETWEEN 2451445 AND 2451446) OR
(Dte = 2451456) OR (Dte = 2451458) OR (Dte BETWEEN 2451465 AND 2451467) OR
(Dte BETWEEN 2451469 AND 2451471) OR (Dte = 2451474) OR
(Dte BETWEEN 2451477 AND 2451501) OR (Dte BETWEEN 2451503 AND 2451509) OR
(Dte BETWEEN 2451511 AND 2451514) OR (Dte BETWEEN 2451518 AND 2451521) OR
(Dte BETWEEN 2451523 AND 2451531) OR (Dte BETWEEN 2451533 AND 2451537) OR
(Dte BETWEEN 2451539 AND 2451544) OR (Dte BETWEEN 2451546 AND 2451551) OR
(Dte BETWEEN 2451553 AND 2451555) OR (Dte = 2451557) OR
(Dte BETWEEN 2451559 AND 2451561) OR (Dte = 2451563) OR
(Dte BETWEEN 2451565 AND 2451566) OR (Dte BETWEEN 2451569 AND 2451571) OR
(Dte = 2451573) OR (Dte = 2451575) OR (Dte = 2451577) OR (Dte = 2451581) OR
(Dte BETWEEN 2451583 AND 2451586) OR (Dte BETWEEN 2451588 AND 2451592) OR
(Dte BETWEEN 2451596 AND 2451598) OR (Dte = 2451600) OR
(Dte BETWEEN 2451602 AND 2451603) OR (Dte = 2451606) OR (Dte = 2451611);
}
} {}
integrity_check {where-99.0}
finish_test