mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-21 09:00:59 +03:00
Add extra assert() statements trying to catch a Mem object in an inconsistent
state. FossilOrigin-Name: 4aeb3ae435c78070232fef21a147fde4e1c5cd31
This commit is contained in:
@@ -600,18 +600,21 @@ int sqlite3VdbeExec(
|
||||
assert( pOp->p1>0 );
|
||||
assert( pOp->p1<=(p->nMem-p->nCursor) );
|
||||
assert( memIsValid(&aMem[pOp->p1]) );
|
||||
assert( memSanity1(&aMem[pOp->p1]) );
|
||||
REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]);
|
||||
}
|
||||
if( (pOp->opflags & OPFLG_IN2)!=0 ){
|
||||
assert( pOp->p2>0 );
|
||||
assert( pOp->p2<=(p->nMem-p->nCursor) );
|
||||
assert( memIsValid(&aMem[pOp->p2]) );
|
||||
assert( memSanity1(&aMem[pOp->p2]) );
|
||||
REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]);
|
||||
}
|
||||
if( (pOp->opflags & OPFLG_IN3)!=0 ){
|
||||
assert( pOp->p3>0 );
|
||||
assert( pOp->p3<=(p->nMem-p->nCursor) );
|
||||
assert( memIsValid(&aMem[pOp->p3]) );
|
||||
assert( memSanity1(&aMem[pOp->p3]) );
|
||||
REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]);
|
||||
}
|
||||
if( (pOp->opflags & OPFLG_OUT2)!=0 ){
|
||||
@@ -2460,6 +2463,7 @@ case OP_Column: {
|
||||
*/
|
||||
assert( p2<pC->nHdrParsed );
|
||||
assert( rc==SQLITE_OK );
|
||||
assert( memSanity1(pDest) );
|
||||
if( pC->szRow>=aOffset[p2+1] ){
|
||||
/* This is the common case where the desired content fits on the original
|
||||
** page - where the content is not on an overflow page */
|
||||
|
||||
@@ -232,6 +232,24 @@ struct Mem {
|
||||
#define memIsValid(M) ((M)->flags & MEM_Undefined)==0
|
||||
#endif
|
||||
|
||||
/*
|
||||
** A sanity check on a Mem object and especially the Mem.z field.
|
||||
** This check says that no more than one of the following may be true:
|
||||
** (1) Mem.z comes from Mem.zMalloc
|
||||
** (2) Mem.z has a destructor Mem.xDel
|
||||
** (3) Mem.z is an ephemeral string
|
||||
** (4) Mem.z is a static string
|
||||
**
|
||||
** Use only inside of an assert() as follows: assert( memSanify(pMem) );
|
||||
*/
|
||||
#ifdef SQLITE_DEBUG
|
||||
#define memSanity1(p) \
|
||||
((((p)->zMalloc && (p)->zMalloc==(p)->z) ? 1 : 0) + \
|
||||
((((p)->flags&MEM_Dyn)&&(p)->xDel) ? 1 : 0) + \
|
||||
(((p)->flags&MEM_Ephem) ? 1 : 0) + \
|
||||
(((p)->flags&MEM_Static) ? 1 : 0) <= 1 )
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Each auxilliary data pointer stored by a user defined function
|
||||
** implementation calling sqlite3_set_auxdata() is stored in an instance
|
||||
|
||||
@@ -1220,6 +1220,7 @@ static void releaseMemArray(Mem *p, int N){
|
||||
}
|
||||
for(pEnd=&p[N]; p<pEnd; p++){
|
||||
assert( (&p[1])==pEnd || p[0].db==p[1].db );
|
||||
assert( memSanity1(p) );
|
||||
|
||||
/* This block is really an inlined version of sqlite3VdbeMemRelease()
|
||||
** that takes advantage of the fact that the memory cell value is
|
||||
|
||||
@@ -67,12 +67,7 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
|
||||
** in pMem->z is discarded.
|
||||
*/
|
||||
int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
|
||||
assert( 1 >=
|
||||
((pMem->zMalloc && pMem->zMalloc==pMem->z) ? 1 : 0) +
|
||||
(((pMem->flags&MEM_Dyn)&&pMem->xDel) ? 1 : 0) +
|
||||
((pMem->flags&MEM_Ephem) ? 1 : 0) +
|
||||
((pMem->flags&MEM_Static) ? 1 : 0)
|
||||
);
|
||||
assert( memSanity1(pMem) );
|
||||
assert( (pMem->flags&MEM_RowSet)==0 );
|
||||
|
||||
/* If the bPreserve flag is set to true, then the memory cell must already
|
||||
@@ -292,6 +287,7 @@ void sqlite3VdbeMemReleaseExternal(Mem *p){
|
||||
** (Mem.memType==MEM_Str).
|
||||
*/
|
||||
void sqlite3VdbeMemRelease(Mem *p){
|
||||
assert( memSanity1(p) );
|
||||
VdbeMemRelease(p);
|
||||
if( p->zMalloc ){
|
||||
sqlite3DbFree(p->db, p->zMalloc);
|
||||
|
||||
Reference in New Issue
Block a user