/ Check-in [793e9422]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Strengthen the sqlite3VdbeMemAboutToChange() run-time verification mechanism to better detect missed calls to AboutToChange().
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 793e942205a12eedb7ecc5ad8a27e3e52bbd4e1d50a0d1453d04a83ba728884e
User & Date: drh 2018-06-11 13:10:45
Context
2018-06-11
17:35
Add the OP_SetTabCol and OP_VerifyTabCol opcodes, only when compiling with SQLITE_DEBUG, to do run-time verification of the column cache. check-in: b37614a3 user: drh tags: trunk
13:10
Strengthen the sqlite3VdbeMemAboutToChange() run-time verification mechanism to better detect missed calls to AboutToChange(). check-in: 793e9422 user: drh tags: trunk
01:30
Always initialize the WhereClause.hasOr field that was added by check-in [292724ffc4]. Error detected by OSSFuzz. check-in: 9faf4171 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbe.h.

   257    257   VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*);
   258    258   sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8);
   259    259   void sqlite3VdbeSetVarmask(Vdbe*, int);
   260    260   #ifndef SQLITE_OMIT_TRACE
   261    261     char *sqlite3VdbeExpandSql(Vdbe*, const char*);
   262    262   #endif
   263    263   int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
          264  +int sqlite3BlobCompare(const Mem*, const Mem*);
   264    265   
   265    266   void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
   266    267   int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
   267    268   int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int);
   268    269   UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*);
   269    270   
   270    271   typedef int (*RecordCompare)(int,const void*,UnpackedRecord*);

Changes to src/vdbeaux.c.

  3908   3908   }
  3909   3909   
  3910   3910   /*
  3911   3911   ** Compare two blobs.  Return negative, zero, or positive if the first
  3912   3912   ** is less than, equal to, or greater than the second, respectively.
  3913   3913   ** If one blob is a prefix of the other, then the shorter is the lessor.
  3914   3914   */
  3915         -static SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){
         3915  +SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){
  3916   3916     int c;
  3917   3917     int n1 = pB1->n;
  3918   3918     int n2 = pB2->n;
  3919   3919   
  3920   3920     /* It is possible to have a Blob value that has some non-zero content
  3921   3921     ** followed by zero content.  But that only comes up for Blobs formed
  3922   3922     ** by the OP_MakeRecord opcode, and such Blobs never get passed into

Changes to src/vdbemem.c.

   882    882   ** copies are not misused.
   883    883   */
   884    884   void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
   885    885     int i;
   886    886     Mem *pX;
   887    887     for(i=0, pX=pVdbe->aMem; i<pVdbe->nMem; i++, pX++){
   888    888       if( pX->pScopyFrom==pMem ){
   889         -      pX->flags |= MEM_Undefined;
          889  +      /* If pX is marked as a shallow copy of pMem, then verify that
          890  +      ** no significant changes have been made to pX since the OP_SCopy.
          891  +      ** A significant change would indicated a missed call to this
          892  +      ** function for pX.  Minor changes, such as adding or removing a
          893  +      ** dual type, are allowed, as long as the underlying value is the
          894  +      ** same. */
          895  +      u16 mFlags = pMem->flags & pX->flags;
          896  +      assert( (mFlags&MEM_Int)==0 || pMem->u.i==pX->u.i );
          897  +      assert( (mFlags&MEM_Real)==0 || pMem->u.r==pX->u.r );
          898  +      assert( (mFlags&MEM_Str)==0  || (pMem->n==pX->n && pMem->z==pX->z) );
          899  +      assert( (mFlags&MEM_Blob)==0  || sqlite3BlobCompare(pMem,pX)==0 );
          900  +      
          901  +      /* pMem is the register that is changing.  But also mark pX as
          902  +      ** undefined so that we can quickly detect the shallow-copy error */
          903  +      pX->flags = MEM_Undefined;
   890    904         pX->pScopyFrom = 0;
   891    905       }
   892    906     }
   893    907     pMem->pScopyFrom = 0;
   894    908   }
   895    909   #endif /* SQLITE_DEBUG */
   896    910