diff options
author | drh <> | 2023-01-25 16:56:24 +0000 |
---|---|---|
committer | drh <> | 2023-01-25 16:56:24 +0000 |
commit | b604f1456e4116b6a60d0d24a0ed1e678617dcf3 (patch) | |
tree | a57d0215a3c6ba7fec7b10d4d90118af14307715 /src | |
parent | a0fe1e7d137334aaf7e6518165894bc5fe15dbe8 (diff) | |
download | sqlite-b604f1456e4116b6a60d0d24a0ed1e678617dcf3.tar.gz sqlite-b604f1456e4116b6a60d0d24a0ed1e678617dcf3.zip |
Enhance the sqlite3_vtab_in_first() and sqlite3_vtab_in_next() interfaces so
that they reliably return SQLITE_ERROR (and not SQLITE_MISUSE) if they are
invoked on a parameter that did not have multi-value IN processing enabled
via a prior call to sqlite3_vtab_in(). See
[forum:/forumpost/a823d4a3d5f73def|forum thread a823d4a3d5f73def].
FossilOrigin-Name: 144326dc171025dc8b5a77bebd8de3c19d5244ab807f5aa41f95313a25b880bc
Diffstat (limited to 'src')
-rw-r--r-- | src/sqlite.h.in | 5 | ||||
-rw-r--r-- | src/vdbe.c | 2 | ||||
-rw-r--r-- | src/vdbeInt.h | 2 | ||||
-rw-r--r-- | src/vdbeapi.c | 22 |
4 files changed, 25 insertions, 6 deletions
diff --git a/src/sqlite.h.in b/src/sqlite.h.in index af482ff0b..0ae65aa75 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -9806,14 +9806,13 @@ int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle); ** is undefined and probably harmful. ** ** The X parameter in a call to sqlite3_vtab_in_first(X,P) or -** sqlite3_vtab_in_next(X,P) must be one of the parameters to the +** sqlite3_vtab_in_next(X,P) should be one of the parameters to the ** xFilter method which invokes these routines, and specifically ** a parameter that was previously selected for all-at-once IN constraint ** processing use the [sqlite3_vtab_in()] interface in the ** [xBestIndex|xBestIndex method]. ^(If the X parameter is not ** an xFilter argument that was selected for all-at-once IN constraint -** processing, then these routines return [SQLITE_MISUSE])^ or perhaps -** exhibit some other undefined or harmful behavior. +** processing, then these routines return [SQLITE_ERROR].)^ ** ** ^(Use these routines to access all values on the right-hand side ** of the IN constraint using code like the following: diff --git a/src/vdbe.c b/src/vdbe.c index db6086233..fb5e04a81 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -8031,7 +8031,7 @@ case OP_VInitIn: { /* out2, ncycle */ pRhs->pOut = &aMem[pOp->p3]; pOut = out2Prerelease(p, pOp); pOut->flags = MEM_Null; - sqlite3VdbeMemSetPointer(pOut, pRhs, "ValueList", sqlite3_free); + sqlite3VdbeMemSetPointer(pOut, pRhs, "ValueList", sqlite3VdbeValueListFree); break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 03f4ec542..b901a0180 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -657,6 +657,8 @@ int sqlite3VdbeSorterRewind(const VdbeCursor *, int *); int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *); int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *); +void sqlite3VdbeValueListFree(void*); + #ifdef SQLITE_DEBUG void sqlite3VdbeIncrWriteCounter(Vdbe*, VdbeCursor*); void sqlite3VdbeAssertAbortable(Vdbe*); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index e080449c5..647976b5f 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -883,6 +883,17 @@ int sqlite3_vtab_nochange(sqlite3_context *p){ } /* +** The destructor function for a ValueList object. This needs to be +** a separate function, unknowable to the application, to ensure that +** calls to sqlite3_vtab_in_first()/sqlite3_vtab_in_next() that are not +** preceeded by activation of IN processing via sqlite3_vtab_int() do not +** try to access a fake ValueList object inserted by a hostile extension. +*/ +void sqlite3VdbeValueListFree(void *pToDelete){ + sqlite3_free(pToDelete); +} + +/* ** Implementation of sqlite3_vtab_in_first() (if bNext==0) and ** sqlite3_vtab_in_next() (if bNext!=0). */ @@ -896,8 +907,15 @@ static int valueFromValueList( *ppOut = 0; if( pVal==0 ) return SQLITE_MISUSE; - pRhs = (ValueList*)sqlite3_value_pointer(pVal, "ValueList"); - if( pRhs==0 ) return SQLITE_MISUSE; + if( pVal->xDel!=sqlite3VdbeValueListFree ){ + return SQLITE_ERROR; + }else{ + assert( (pVal->flags&(MEM_TypeMask|MEM_Term|MEM_Subtype)) == + (MEM_Null|MEM_Term|MEM_Subtype) ); + assert( pVal->eSubtype=='p' ); + assert( pVal->u.zPType!=0 && strcmp(pVal->u.zPType,"ValueList")==0 ); + pRhs = (ValueList*)pVal->z; + } if( bNext ){ rc = sqlite3BtreeNext(pRhs->pCsr, 0); }else{ |