/ Check-in [8cb2b02b]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Merge from trunk the fix for the crash on a corrupt database.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | threads
Files: files | file ages | folders
SHA1: 8cb2b02baa7ef9aa96319e977f0315328f944237
User & Date: drh 2014-03-26 19:45:01
Context
2014-03-28
19:18
Merge latest changes from orderby-planning branch. check-in: 4c7fb542 user: dan tags: threads
2014-03-26
19:45
Merge from trunk the fix for the crash on a corrupt database. check-in: 8cb2b02b user: drh tags: threads
15:14
Add an extra test case for the potential buffer overread patched by [28ddecff04]. check-in: f585f5d7 user: dan tags: trunk
2014-03-25
14:12
Enable four sorting threads by default in the command-line shell. check-in: 1cab8357 user: drh tags: threads
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbeaux.c.

  3430   3430       szHdr1 = aKey1[0];
  3431   3431       d1 = szHdr1 + sqlite3VdbeSerialTypeLen(s1);
  3432   3432       i = 1;
  3433   3433       pRhs++;
  3434   3434     }else{
  3435   3435       idx1 = getVarint32(aKey1, szHdr1);
  3436   3436       d1 = szHdr1;
         3437  +    if( d1>(unsigned)nKey1 ) return 1;  /* Corruption */
  3437   3438       i = 0;
  3438   3439     }
  3439   3440   
  3440   3441     VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */
  3441   3442     assert( pPKey2->pKeyInfo->nField+pPKey2->pKeyInfo->nXField>=pPKey2->nField 
  3442   3443          || CORRUPT_DB );
  3443   3444     assert( pPKey2->pKeyInfo->aSortOrder!=0 );
................................................................................
  3585   3586   }
  3586   3587   
  3587   3588   /*
  3588   3589   ** This function is an optimized version of sqlite3VdbeRecordCompare() 
  3589   3590   ** that (a) the first field of pPKey2 is an integer, and (b) the 
  3590   3591   ** size-of-header varint at the start of (pKey1/nKey1) fits in a single
  3591   3592   ** byte (i.e. is less than 128).
         3593  +**
         3594  +** To avoid concerns about buffer overreads, this routine is only used
         3595  +** on schemas where the maximum valid header size is 63 bytes or less.
  3592   3596   */
  3593   3597   static int vdbeRecordCompareInt(
  3594   3598     int nKey1, const void *pKey1, /* Left key */
  3595   3599     const UnpackedRecord *pPKey2, /* Right key */
  3596   3600     int bSkip                     /* Ignored */
  3597   3601   ){
  3598   3602     const u8 *aKey = &((const u8*)pKey1)[*(const u8*)pKey1 & 0x3F];
................................................................................
  3601   3605     u32 y;
  3602   3606     u64 x;
  3603   3607     i64 v = pPKey2->aMem[0].u.i;
  3604   3608     i64 lhs;
  3605   3609     UNUSED_PARAMETER(bSkip);
  3606   3610   
  3607   3611     assert( bSkip==0 );
         3612  +  assert( (*(u8*)pKey1)<=0x3F || CORRUPT_DB );
  3608   3613     switch( serial_type ){
  3609   3614       case 1: { /* 1-byte signed integer */
  3610   3615         lhs = ONE_BYTE_INT(aKey);
  3611   3616         testcase( lhs<0 );
  3612   3617         break;
  3613   3618       }
  3614   3619       case 2: { /* 2-byte signed integer */

Changes to test/corruptI.test.

    28     28   # Initialize the database.
    29     29   #
    30     30   do_execsql_test 1.1 {
    31     31     PRAGMA page_size=1024;
    32     32     PRAGMA auto_vacuum=0;
    33     33     CREATE TABLE t1(a);
    34     34     CREATE INDEX i1 ON t1(a);
    35         -  INSERT INTO t1 VALUES('a');
           35  +  INSERT INTO t1 VALUES('abcdefghijklmnop');
    36     36   } {}
    37     37   db close
    38     38   
    39     39   do_test 1.2 {
    40     40     set offset [hexio_get_int [hexio_read test.db [expr 2*1024 + 8] 2]]
    41     41     set off [expr 2*1024 + $offset + 1]
    42         -  hexio_write test.db $off FF06
    43         -
    44         -  breakpoint
           42  +  hexio_write test.db $off 7f06
           43  +  sqlite3 db test.db
           44  +  catchsql { SELECT * FROM t1 WHERE a = 10 }
           45  +} {0 {}}
    45     46   
           47  +do_test 1.3 {
           48  +  db close
           49  +  set offset [hexio_get_int [hexio_read test.db [expr 2*1024 + 8] 2]]
           50  +  set off [expr 2*1024 + $offset + 1]
           51  +  hexio_write test.db $off FFFF7f02
    46     52     sqlite3 db test.db
    47     53     catchsql { SELECT * FROM t1 WHERE a = 10 }
           54  +} {0 {}}
           55  +
           56  +do_test 2.0 {
           57  +  execsql {
           58  +    CREATE TABLE r(x);
           59  +    INSERT INTO r VALUES('ABCDEFGHIJK');
           60  +    CREATE INDEX r1 ON r(x);
           61  +  }
           62  +  set pg [db one {SELECT rootpage FROM sqlite_master WHERE name = 'r1'}]
           63  +} {5}
           64  +
           65  +do_test 2.1 {
           66  +  db close
           67  +  set offset [hexio_get_int [hexio_read test.db [expr (5-1)*1024 + 8] 2]]
           68  +  set off [expr (5-1)*1024 + $offset + 1]
           69  +  hexio_write test.db $off FFFF0004
           70  +  sqlite3 db test.db
           71  +  catchsql { SELECT * FROM r WHERE x >= 10.0 }
           72  +} {1 {database disk image is malformed}}
           73  +
           74  +do_test 2.2 {
           75  +  catchsql { SELECT * FROM r WHERE x >= 10 }
    48     76   } {1 {database disk image is malformed}}
    49     77   
    50     78   
    51     79   finish_test
    52         -

Changes to test/speedtest1.c.

   470    470       sqlite3_bind_text(g.pStmt, 3, zNum, -1, SQLITE_STATIC);
   471    471       speedtest1_run();
   472    472     }
   473    473     speedtest1_exec("COMMIT");
   474    474     speedtest1_end_test();
   475    475   
   476    476   
   477         -  n = g.szTest/2;
          477  +  n = 25;
   478    478     speedtest1_begin_test(130, "%d SELECTS, numeric BETWEEN, unindexed", n);
   479    479     speedtest1_exec("BEGIN");
   480    480     speedtest1_prepare(
   481    481       "SELECT count(*), avg(b), sum(length(c)) FROM t1\n"
   482    482       " WHERE b BETWEEN ?1 AND ?2; -- %d times", n
   483    483     );
   484    484     for(i=1; i<=n; i++){
................................................................................
   488    488       sqlite3_bind_int(g.pStmt, 2, x2);
   489    489       speedtest1_run();
   490    490     }
   491    491     speedtest1_exec("COMMIT");
   492    492     speedtest1_end_test();
   493    493   
   494    494   
   495         -  n = g.szTest/5;
          495  +  n = 10;
   496    496     speedtest1_begin_test(140, "%d SELECTS, LIKE, unindexed", n);
   497    497     speedtest1_exec("BEGIN");
   498    498     speedtest1_prepare(
   499    499       "SELECT count(*), avg(b), sum(length(c)) FROM t1\n"
   500    500       " WHERE c LIKE ?1; -- %d times", n
   501    501     );
          502  +  for(i=1; i<=n; i++){
          503  +    x1 = speedtest1_random()%maxb;
          504  +    zNum[0] = '%';
          505  +    len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
          506  +    zNum[len] = '%';
          507  +    zNum[len+1] = 0;
          508  +    sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC);
          509  +    speedtest1_run();
          510  +  }
          511  +  speedtest1_exec("COMMIT");
          512  +  speedtest1_end_test();
          513  +
          514  +
          515  +  n = 10;
          516  +  speedtest1_begin_test(142, "%d SELECTS w/ORDER BY, unindexed", n);
          517  +  speedtest1_exec("BEGIN");
          518  +  speedtest1_prepare(
          519  +    "SELECT a, b, c FROM t1 WHERE c LIKE ?1\n"
          520  +    " ORDER BY a; -- %d times", n
          521  +  );
          522  +  for(i=1; i<=n; i++){
          523  +    x1 = speedtest1_random()%maxb;
          524  +    zNum[0] = '%';
          525  +    len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
          526  +    zNum[len] = '%';
          527  +    zNum[len+1] = 0;
          528  +    sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC);
          529  +    speedtest1_run();
          530  +  }
          531  +  speedtest1_exec("COMMIT");
          532  +  speedtest1_end_test();
          533  +
          534  +  n = 10; //g.szTest/5;
          535  +  speedtest1_begin_test(145, "%d SELECTS w/ORDER BY and LIMIT, unindexed", n);
          536  +  speedtest1_exec("BEGIN");
          537  +  speedtest1_prepare(
          538  +    "SELECT a, b, c FROM t1 WHERE c LIKE ?1\n"
          539  +    " ORDER BY a LIMIT 10; -- %d times", n
          540  +  );
   502    541     for(i=1; i<=n; i++){
   503    542       x1 = speedtest1_random()%maxb;
   504    543       zNum[0] = '%';
   505    544       len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
   506    545       zNum[len] = '%';
   507    546       zNum[len+1] = 0;
   508    547       sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC);