SQLite

Check-in [60de5f2342]
Login

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

Overview
Comment:Fix an obscure memory leak found by libfuzzer that may occur under some circumstances if expanding a "*" expression causes a SELECT to return more than 32767 columns.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 60de5f23424552c98aa760ac89149a3d51f895be
User & Date: dan 2015-11-21 19:43:29.760
Context
2015-11-24
00:49
Do not try to eliminate No-ops at the end of VDBE program as this can cause problems for some DISTINCT handling algorithms, and does not improve performance. This also fixes an assertion fault found by libFuzzer. (check-in: 19d9f9ce69 user: drh tags: trunk)
2015-11-23
21:09
Add experimental support for LIKE, GLOB and REGEXP to the virtual table interface. (check-in: 277a5b4027 user: dan tags: vtab-like-operator)
17:14
Merge latest trunk changes with this branch. (check-in: 8f1ef0904d user: dan tags: schemalint)
2015-11-21
19:43
Fix an obscure memory leak found by libfuzzer that may occur under some circumstances if expanding a "*" expression causes a SELECT to return more than 32767 columns. (check-in: 60de5f2342 user: dan tags: trunk)
17:27
Fix over-length source code lines. No logic changes. (check-in: 198d191b2f user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/select.c.
1609
1610
1611
1612
1613
1614
1615

1616
1617
1618
1619
1620
1621
1622
    nCol = pEList->nExpr;
    aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol);
    testcase( aCol==0 );
  }else{
    nCol = 0;
    aCol = 0;
  }

  *pnCol = nCol;
  *paCol = aCol;

  for(i=0, pCol=aCol; i<nCol && !db->mallocFailed; i++, pCol++){
    /* Get an appropriate name for the column
    */
    p = sqlite3ExprSkipCollate(pEList->a[i].pExpr);







>







1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
    nCol = pEList->nExpr;
    aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol);
    testcase( aCol==0 );
  }else{
    nCol = 0;
    aCol = 0;
  }
  assert( nCol==(i16)nCol );
  *pnCol = nCol;
  *paCol = aCol;

  for(i=0, pCol=aCol; i<nCol && !db->mallocFailed; i++, pCol++){
    /* Get an appropriate name for the column
    */
    p = sqlite3ExprSkipCollate(pEList->a[i].pExpr);
4451
4452
4453
4454
4455
4456
4457

4458
4459
4460
4461
4462
4463
4464
    }
    sqlite3ExprListDelete(db, pEList);
    p->pEList = pNew;
  }
#if SQLITE_MAX_COLUMN
  if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
    sqlite3ErrorMsg(pParse, "too many columns in result set");

  }
#endif
  return WRC_Continue;
}

/*
** No-op routine for the parse-tree walker.







>







4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
    }
    sqlite3ExprListDelete(db, pEList);
    p->pEList = pNew;
  }
#if SQLITE_MAX_COLUMN
  if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
    sqlite3ErrorMsg(pParse, "too many columns in result set");
    return WRC_Abort;
  }
#endif
  return WRC_Continue;
}

/*
** No-op routine for the parse-tree walker.
Changes to test/sqllimits1.test.
870
871
872
873
874
875
876











877
878
879
880
881
do_test sqllimits1-16.2 {
  set ::format "[string repeat A 60][string repeat "%J" $::N]"
  catchsql {
    SELECT strftime($::format, 1);
  }
} {1 {string or blob too big}}













foreach {key value} [array get saved] {
  catch {set $key $value}
}
finish_test







>
>
>
>
>
>
>
>
>
>
>





870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
do_test sqllimits1-16.2 {
  set ::format "[string repeat A 60][string repeat "%J" $::N]"
  catchsql {
    SELECT strftime($::format, 1);
  }
} {1 {string or blob too big}}

do_catchsql_test sqllimits1.17.0 {
  SELECT *,*,*,*,*,*,*,* FROM (
  SELECT *,*,*,*,*,*,*,* FROM (
  SELECT *,*,*,*,*,*,*,* FROM (
  SELECT *,*,*,*,*,*,*,* FROM (
  SELECT *,*,*,*,*,*,*,* FROM (
    SELECT 1,2,3,4,5,6,7,8,9,10
  )
  ))))
} "1 {too many columns in result set}"


foreach {key value} [array get saved] {
  catch {set $key $value}
}
finish_test