/ Check-in [3fb40f51]
Login

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

Overview
Comment:Fix the instr() SQL function so that it makes a copy of its argument before changing the datatype, since the datatype affects processing. Also fix the sqlite3_value_text() routine so that it always works even for values obtained form sqlite3_value_dup(). Ticket [587791f92620090e]
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 3fb40f518086c1e8d11eb1f4134e965450dbedfa4277bce39ef1e969fc747d38
User & Date: drh 2019-09-17 03:16:29
References
2019-09-18
11:16
Fix an OOB read in the INSTR() function introduced yesterday by check-in [3fb40f518086c1e8] and detected by OSSFuzz. The test case is in TH3. check-in: d49047c1 user: drh tags: trunk
Context
2019-09-17
13:30
Test cases for ticket [587791f92620090e] check-in: ca0e3a83 user: drh tags: trunk
03:16
Fix the instr() SQL function so that it makes a copy of its argument before changing the datatype, since the datatype affects processing. Also fix the sqlite3_value_text() routine so that it always works even for values obtained form sqlite3_value_dup(). Ticket [587791f92620090e] check-in: 3fb40f51 user: drh tags: trunk
2019-09-16
20:16
Improved type information display when tracing VDBE execution. check-in: ee83d8e3 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/func.c.

   199    199     const unsigned char *zNeedle;
   200    200     int nHaystack;
   201    201     int nNeedle;
   202    202     int typeHaystack, typeNeedle;
   203    203     int N = 1;
   204    204     int isText;
   205    205     unsigned char firstChar;
          206  +  sqlite3_value *pC1 = 0;
          207  +  sqlite3_value *pC2 = 0;
   206    208   
   207    209     UNUSED_PARAMETER(argc);
   208    210     typeHaystack = sqlite3_value_type(argv[0]);
   209    211     typeNeedle = sqlite3_value_type(argv[1]);
   210    212     if( typeHaystack==SQLITE_NULL || typeNeedle==SQLITE_NULL ) return;
   211    213     nHaystack = sqlite3_value_bytes(argv[0]);
   212    214     nNeedle = sqlite3_value_bytes(argv[1]);
   213    215     if( nNeedle>0 ){
   214    216       if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){
   215    217         zHaystack = sqlite3_value_blob(argv[0]);
   216    218         zNeedle = sqlite3_value_blob(argv[1]);
   217    219         isText = 0;
   218         -    }else{
          220  +    }else if( typeHaystack!=SQLITE_BLOB && typeNeedle!=SQLITE_BLOB ){
   219    221         zHaystack = sqlite3_value_text(argv[0]);
   220    222         zNeedle = sqlite3_value_text(argv[1]);
   221    223         isText = 1;
          224  +    }else{
          225  +      pC1 = sqlite3_value_dup(argv[0]);
          226  +      zHaystack = sqlite3_value_text(pC1);
          227  +      pC2 = sqlite3_value_dup(argv[1]);
          228  +      zNeedle = sqlite3_value_text(pC2);
          229  +      isText = 1;
   222    230       }
   223         -    if( zNeedle==0 || (nHaystack && zHaystack==0) ) return;
          231  +    if( zNeedle==0 || (nHaystack && zHaystack==0) ){
          232  +      sqlite3_result_error_nomem(context);
          233  +      goto endInstr;
          234  +    }
   224    235       firstChar = zNeedle[0];
   225    236       while( nNeedle<=nHaystack
   226    237          && (zHaystack[0]!=firstChar || memcmp(zHaystack, zNeedle, nNeedle)!=0)
   227    238       ){
   228    239         N++;
   229    240         do{
   230    241           nHaystack--;
   231    242           zHaystack++;
   232    243         }while( isText && (zHaystack[0]&0xc0)==0x80 );
   233    244       }
   234    245       if( nNeedle>nHaystack ) N = 0;
   235    246     }
   236    247     sqlite3_result_int(context, N);
          248  +endInstr:
          249  +  sqlite3_value_free(pC1);
          250  +  sqlite3_value_free(pC2);
   237    251   }
   238    252   
   239    253   /*
   240    254   ** Implementation of the printf() function.
   241    255   */
   242    256   static void printfFunc(
   243    257     sqlite3_context *context,

Changes to src/vdbemem.c.

   228    228     ** contain a valid string or blob value.  */
   229    229     assert( bPreserve==0 || pMem->flags&(MEM_Blob|MEM_Str) );
   230    230     testcase( bPreserve && pMem->z==0 );
   231    231   
   232    232     assert( pMem->szMalloc==0
   233    233          || pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) );
   234    234     if( pMem->szMalloc>0 && bPreserve && pMem->z==pMem->zMalloc ){
   235         -    pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
          235  +    if( pMem->db ){
          236  +      pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
          237  +    }else{
          238  +      pMem->zMalloc = sqlite3Realloc(pMem->z, n);
          239  +      if( pMem->zMalloc==0 ) sqlite3_free(pMem->z);
          240  +      pMem->z = pMem->zMalloc;
          241  +    }
   236    242       bPreserve = 0;
   237    243     }else{
   238    244       if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
   239    245       pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
   240    246     }
   241    247     if( pMem->zMalloc==0 ){
   242    248       sqlite3VdbeMemSetNull(pMem);