/ Check-in [62382719]
Login

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

Overview
Comment:Fix an integer overflow bug in vdbesort.c.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:623827192532f08b68bc0eb9ed1449e173361f0c
User & Date: dan 2014-11-25 18:59:55
Context
2014-11-27
03:46
Fix a problem in the new b-tree balancer that was causing corruption of the fragmentation count. check-in: f242394e user: drh tags: trunk
2014-11-25
18:59
Fix an integer overflow bug in vdbesort.c. check-in: 62382719 user: dan tags: trunk
2014-11-22
21:37
Always reinitialized the Index.bUnordered and Index.noSkipscan flags before rereading the sqlite_stat1 table, even if SQLITE_ENABLE_STAT4 is defined. check-in: 1e1221fc user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Changes to src/vdbesort.c.

   143    143   ** messages to stderr that may be helpful in understanding the performance
   144    144   ** characteristics of the sorter in multi-threaded mode.
   145    145   */
   146    146   #if 0
   147    147   # define SQLITE_DEBUG_SORTER_THREADS 1
   148    148   #endif
   149    149   
          150  +/*
          151  +** Hard-coded maximum amount of data to accumulate in memory before flushing
          152  +** to a level 0 PMA. The purpose of this limit is to prevent various integer
          153  +** overflows. 512MiB.
          154  +*/
          155  +#define SQLITE_MAX_MXPMASIZE    (1<<29)
          156  +
   150    157   /*
   151    158   ** Private objects used by the sorter
   152    159   */
   153    160   typedef struct MergeEngine MergeEngine;     /* Merge PMAs together */
   154    161   typedef struct PmaReader PmaReader;         /* Incrementally read one PMA */
   155    162   typedef struct PmaWriter PmaWriter;         /* Incrementally write one PMA */
   156    163   typedef struct SorterRecord SorterRecord;   /* A record being sorted */
................................................................................
   841    848         pTask->pSorter = pSorter;
   842    849       }
   843    850   
   844    851       if( !sqlite3TempInMemory(db) ){
   845    852         pSorter->mnPmaSize = SORTER_MIN_WORKING * pgsz;
   846    853         mxCache = db->aDb[0].pSchema->cache_size;
   847    854         if( mxCache<SORTER_MIN_WORKING ) mxCache = SORTER_MIN_WORKING;
   848         -      pSorter->mxPmaSize = mxCache * pgsz;
          855  +      pSorter->mxPmaSize = MIN((i64)mxCache*pgsz, SQLITE_MAX_MXPMASIZE);
   849    856   
   850    857         /* EVIDENCE-OF: R-26747-61719 When the application provides any amount of
   851    858         ** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary
   852    859         ** large heap allocations.
   853    860         */
   854    861         if( sqlite3GlobalConfig.pScratch==0 ){
   855    862           assert( pSorter->iMemory==0 );

Added test/bigsort.test.

            1  +# 2014 November 26
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +
           13  +set testdir [file dirname $argv0]
           14  +source $testdir/tester.tcl
           15  +set testprefix bigsort
           16  +
           17  +#--------------------------------------------------------------------
           18  +# At one point there was an overflow problem if the product of the 
           19  +# cache-size and page-size was larger than 2^31. Causing an infinite 
           20  +# loop if the product was also an integer multiple of 2^32, or 
           21  +# inefficiency otherwise.
           22  +#
           23  +do_execsql_test 1.0 {
           24  +  PRAGMA page_size = 1024;
           25  +  CREATE TABLE t1(a, b);
           26  +  BEGIN;
           27  +  WITH data(x,y) AS (
           28  +    SELECT 1, zeroblob(10000)
           29  +    UNION ALL
           30  +    SELECT x+1, y FROM data WHERE x < 300000
           31  +  )
           32  +  INSERT INTO t1 SELECT * FROM data;
           33  +  COMMIT;
           34  +}
           35  +do_execsql_test 1.1 {
           36  +  PRAGMA cache_size = 4194304;
           37  +  CREATE INDEX i1 ON t1(a, b);
           38  +}
           39  +
           40  +
           41  +finish_test
           42  +
           43  +

Changes to test/permutations.test.

   109    109     speed1.test speed1p.test speed2.test speed3.test speed4.test 
   110    110     speed4p.test sqllimits1.test tkt2686.test thread001.test thread002.test
   111    111     thread003.test thread004.test thread005.test trans2.test vacuum3.test 
   112    112     incrvacuum_ioerr.test autovacuum_crash.test btree8.test shared_err.test
   113    113     vtab_err.test walslow.test walcrash.test walcrash3.test
   114    114     walthread.test rtree3.test indexfault.test securedel2.test
   115    115     sort3.test sort4.test fts4growth.test fts4growth2.test
          116  +  bigsort.test
   116    117   }]
   117    118   if {[info exists ::env(QUICKTEST_INCLUDE)]} {
   118    119     set allquicktests [concat $allquicktests $::env(QUICKTEST_INCLUDE)]
   119    120   }
   120    121   
   121    122   #############################################################################
   122    123   # Start of tests