/ Check-in [f41a0391]
Login

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

Overview
Comment:Fix a buffer overrun in the code for handling IN(...) operators when the LHS of the operator contains indexed columns or expressions.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | rowvalue
Files: files | file ages | folders
SHA1:f41a0391b732a8c4ad188163f34a0f4a22237bb5
User & Date: dan 2016-08-24 12:22:17
Context
2016-08-24
15:37
Add a NEVER() on an unreachable branch in comparisonAffinity(). check-in: 505a2f20 user: drh tags: rowvalue
12:22
Fix a buffer overrun in the code for handling IN(...) operators when the LHS of the operator contains indexed columns or expressions. check-in: f41a0391 user: dan tags: rowvalue
00:51
The previous OOM fix was bad. Back it out and replace it with a better one. check-in: 1e3bc369 user: drh tags: rowvalue
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/wherecode.c.

467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
...
485
486
487
488
489
490
491

492
493
494
495
496
497
498
    pLevel->u.in.aInLoop =
       sqlite3DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop,
                              sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn);
    pIn = pLevel->u.in.aInLoop;
    if( pIn ){
      int iMap = 0;               /* Index in aiMap[] */
      pIn += i;
      for(i=iEq;i<pLoop->nLTerm; i++, pIn++){
        int iOut = iReg;
        if( pLoop->aLTerm[i]->pExpr==pX ){
          if( eType==IN_INDEX_ROWID ){
            assert( nEq==1 && i==iEq );
            pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iReg);
          }else{
            int iCol = aiMap ? aiMap[iMap++] : 0;
................................................................................
          sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v);
          if( i==iEq ){
            pIn->iCur = iTab;
            pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen;
          }else{
            pIn->eEndLoopOp = OP_Noop;
          }

        }
      }
    }else{
      pLevel->u.in.nIn = 0;
    }
    sqlite3DbFree(pParse->db, aiMap);
#endif







|







 







>







467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
...
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
    pLevel->u.in.aInLoop =
       sqlite3DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop,
                              sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn);
    pIn = pLevel->u.in.aInLoop;
    if( pIn ){
      int iMap = 0;               /* Index in aiMap[] */
      pIn += i;
      for(i=iEq;i<pLoop->nLTerm; i++){
        int iOut = iReg;
        if( pLoop->aLTerm[i]->pExpr==pX ){
          if( eType==IN_INDEX_ROWID ){
            assert( nEq==1 && i==iEq );
            pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iReg);
          }else{
            int iCol = aiMap ? aiMap[iMap++] : 0;
................................................................................
          sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v);
          if( i==iEq ){
            pIn->iCur = iTab;
            pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen;
          }else{
            pIn->eEndLoopOp = OP_Noop;
          }
          pIn++;
        }
      }
    }else{
      pLevel->u.in.nIn = 0;
    }
    sqlite3DbFree(pParse->db, aiMap);
#endif

Changes to test/rowvalue.test.

215
216
217
218
219
220
221




222





223
  2 "(a, b) > (2, 2)" {3 4 5}
  3 "(a, b) < (4, 5)" {1 2 3 4}
  4 "(a, b) < (4, 3)" {1 2 3}
} {
  do_execsql_test 9.$tn "SELECT c FROM t2 WHERE $q" $res
} 











finish_test







>
>
>
>

>
>
>
>
>

215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
  2 "(a, b) > (2, 2)" {3 4 5}
  3 "(a, b) < (4, 5)" {1 2 3 4}
  4 "(a, b) < (4, 3)" {1 2 3}
} {
  do_execsql_test 9.$tn "SELECT c FROM t2 WHERE $q" $res
} 

do_execsql_test 10.0 {
  CREATE TABLE dual(dummy); INSERT INTO dual(dummy) VALUES('X');
  CREATE TABLE t3(a TEXT,b TEXT,c TEXT,d TEXT,e TEXT,f TEXT);
  CREATE INDEX t3x ON t3(b,c,d,e,f);

  SELECT a FROM t3
    WHERE (c,d) IN (SELECT 'c','d' FROM dual)
    AND (a,b,e) IN (SELECT 'a','b','d' FROM dual);
}

finish_test