/ Check-in [713caa38]
Login

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

Overview
Comment:Avoid unwelcomed side effects on the input operands in the OP_Concat operator. Fix for ticket [3be1295b264be2fac49b681]
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 713caa382cf7ddef872e510a76a5fca40be1a8d8876ce2f91b632bb0810a6630
User & Date: drh 2019-05-01 15:32:40
References
2019-05-02
00:52
Fix an issue (discovered by OSSFuzz) in the enhanced OP_Concat operator from check-in [713caa382cf7dd] earlier today. check-in: 3e897702 user: drh tags: trunk
Context
2019-05-01
17:32
Fix a case in wapptest.tcl where a failed test might report 0 errors. check-in: 2be1ed70 user: dan tags: trunk
15:32
Avoid unwelcomed side effects on the input operands in the OP_Concat operator. Fix for ticket [3be1295b264be2fac49b681] check-in: 713caa38 user: drh tags: trunk
15:25
Update wapptest.tcl so that it deletes extra files if the "Keep files:" checkbox is clear. Set it by default. check-in: 09623cc4 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

   191    191         if( (mNever&0x08)!=0 && (I&0x05)!=0) I |= 0x05; /*NO_TEST*/
   192    192       }
   193    193       sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg,
   194    194                                       iSrcLine&0xffffff, I, M);
   195    195     }
   196    196   #endif
   197    197   
   198         -/*
   199         -** Convert the given register into a string if it isn't one
   200         -** already. Return non-zero if a malloc() fails.
   201         -*/
   202         -#define Stringify(P, enc) \
   203         -   if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc,0)) \
   204         -     { goto no_mem; }
   205         -
   206    198   /*
   207    199   ** An ephemeral string value (signified by the MEM_Ephem flag) contains
   208    200   ** a pointer to a dynamically allocated string where some other entity
   209    201   ** is responsible for deallocating that string.  Because the register
   210    202   ** does not control the string, it might be deleted without the register
   211    203   ** knowing it.
   212    204   **
................................................................................
  1459   1451   **   P3 = P2 || P1
  1460   1452   **
  1461   1453   ** It is illegal for P1 and P3 to be the same register. Sometimes,
  1462   1454   ** if P3 is the same register as P2, the implementation is able
  1463   1455   ** to avoid a memcpy().
  1464   1456   */
  1465   1457   case OP_Concat: {           /* same as TK_CONCAT, in1, in2, out3 */
  1466         -  i64 nByte;
         1458  +  i64 nByte;          /* Total size of the output string or blob */
         1459  +  u16 flags1;         /* Initial flags for P1 */
         1460  +  u16 flags2;         /* Initial flags for P2 */
  1467   1461   
  1468   1462     pIn1 = &aMem[pOp->p1];
  1469   1463     pIn2 = &aMem[pOp->p2];
  1470   1464     pOut = &aMem[pOp->p3];
         1465  +  testcase( pIn1==pIn2 );
         1466  +  testcase( pOut==pIn2 );
  1471   1467     assert( pIn1!=pOut );
  1472         -  if( (pIn1->flags | pIn2->flags) & MEM_Null ){
         1468  +  flags1 = pIn1->flags;
         1469  +  testcase( flags1 & MEM_Null );
         1470  +  testcase( pIn2->flags & MEM_Null );
         1471  +  if( (flags1 | pIn2->flags) & MEM_Null ){
  1473   1472       sqlite3VdbeMemSetNull(pOut);
  1474   1473       break;
  1475   1474     }
  1476         -  if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem;
  1477         -  Stringify(pIn1, encoding);
  1478         -  Stringify(pIn2, encoding);
         1475  +  if( (flags1 & (MEM_Str|MEM_Blob))==0 ){
         1476  +    if( sqlite3VdbeMemStringify(pIn1,encoding,0) ) goto no_mem;
         1477  +  }else if( (flags1 & MEM_Zero)!=0 ){
         1478  +    if( sqlite3VdbeMemExpandBlob(pIn1) ) goto no_mem;
         1479  +  }
         1480  +  flags2 = pIn2->flags;
         1481  +  if( (flags2 & (MEM_Str|MEM_Blob))==0 ){
         1482  +    if( sqlite3VdbeMemStringify(pIn2,encoding,0) ) goto no_mem;
         1483  +  }else if( (flags2 & MEM_Zero)!=0 ){
         1484  +    if( sqlite3VdbeMemExpandBlob(pIn2) ) goto no_mem;
         1485  +  }
  1479   1486     nByte = pIn1->n + pIn2->n;
  1480   1487     if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
  1481   1488       goto too_big;
  1482   1489     }
  1483   1490     if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){
  1484   1491       goto no_mem;
  1485   1492     }
  1486   1493     MemSetTypeFlag(pOut, MEM_Str);
  1487   1494     if( pOut!=pIn2 ){
  1488   1495       memcpy(pOut->z, pIn2->z, pIn2->n);
         1496  +    assert( (pIn2->flags & MEM_Dyn) == (flags2 & MEM_Dyn) );
         1497  +    pIn2->flags = flags2;
  1489   1498     }
  1490   1499     memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n);
         1500  +  assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) );
         1501  +  pIn1->flags = flags1;
  1491   1502     pOut->z[nByte]=0;
  1492   1503     pOut->z[nByte+1] = 0;
  1493   1504     pOut->flags |= MEM_Term;
  1494   1505     pOut->n = (int)nByte;
  1495   1506     pOut->enc = encoding;
  1496   1507     UPDATE_MAX_BLOBSIZE(pOut);
  1497   1508     break;

Changes to test/index.test.

   734    734        CREATE TEMP TABLE t6(x);
   735    735        INSERT INTO temp.t6 values(1),(5),(9);
   736    736        CREATE INDEX temp.i21 ON t6(x);
   737    737        SELECT x FROM t6 ORDER BY x DESC;
   738    738     }
   739    739   } {0 {9 5 1}}
   740    740   
          741  +# 2019-05-01 ticket https://www.sqlite.org/src/info/3be1295b264be2fa
          742  +do_execsql_test index-22.0 {
          743  +  DROP TABLE IF EXISTS t1;
          744  +  CREATE TABLE t1(a, b TEXT);
          745  +  CREATE UNIQUE INDEX IF NOT EXISTS x1 ON t1(b==0);
          746  +  CREATE INDEX IF NOT EXISTS x2 ON t1(a || 0) WHERE b;
          747  +  INSERT INTO t1(a,b) VALUES('a',1),('a',0);
          748  +  SELECT a, b, '|' FROM t1;
          749  +} {a 1 | a 0 |}
   741    750      
   742    751   
   743    752   finish_test