/ Check-in [d74fbb81]
Login

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

Overview
Comment:Test another corruption case in btree.c. And an IO error related scenario. (CVS 5371)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: d74fbb81ca3f973ac46534344e5076afc5dd5491
User & Date: danielk1977 2008-07-08 17:13:59
Context
2008-07-08
17:43
Prevent the flattening optimization from transforming a to a query with an illegal ORDER BY clause. (CVS 5372) check-in: 6c2adade user: danielk1977 tags: trunk
17:13
Test another corruption case in btree.c. And an IO error related scenario. (CVS 5371) check-in: d74fbb81 user: danielk1977 tags: trunk
15:59
3 more coverage tests for btree.c. (CVS 5370) check-in: 96df0a5f user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/btree.c.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.471 2008/07/04 17:52:43 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
** Including a description of file format and an overview of operation.
*/
#include "btreeInt.h"

................................................................................
    if( rc!=SQLITE_OK ){
      goto set_child_ptrmaps_out;
    }

    if( !pPage->leaf ){
      Pgno childPgno = get4byte(pCell);
      rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno);
      if( rc!=SQLITE_OK ) goto set_child_ptrmaps_out;
    }
  }

  if( !pPage->leaf ){
    Pgno childPgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
    rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno);
  }







|







 







|







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.472 2008/07/08 17:13:59 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
** Including a description of file format and an overview of operation.
*/
#include "btreeInt.h"

................................................................................
    if( rc!=SQLITE_OK ){
      goto set_child_ptrmaps_out;
    }

    if( !pPage->leaf ){
      Pgno childPgno = get4byte(pCell);
      rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno);
       if( rc!=SQLITE_OK ) goto set_child_ptrmaps_out;
    }
  }

  if( !pPage->leaf ){
    Pgno childPgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
    rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno);
  }

Changes to test/corrupt2.test.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351


352
353
354
355
356
357
358
359
360
361
362
363
364
365







































366
367
368
369
370
371
372
...
385
386
387
388
389
390
391
392
393
394
395
396
397
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests to make sure SQLite does not crash or
# segfault if it sees a corrupt database file.
#
# $Id: corrupt2.test,v 1.12 2008/07/08 15:59:52 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# The following tests - corrupt2-1.* - create some databases corrupted in
# specific ways and ensure that SQLite detects them as corrupt.
#
................................................................................
        COMMIT;
      }
    } {1 {database disk image is malformed}}
  }
}


corruption_test -sqlprep {
  PRAGMA page_size = 1024;
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
  CREATE INDEX i1 ON t1(b);
  INSERT INTO t1 VALUES(1, randomblob(50));
  INSERT INTO t1 SELECT NULL, randomblob(50) FROM t1;
  INSERT INTO t1 SELECT NULL, randomblob(50) FROM t1;
  INSERT INTO t1 SELECT NULL, randomblob(50) FROM t1;
  INSERT INTO t1 SELECT NULL, randomblob(50) FROM t1;
  INSERT INTO t1 SELECT NULL, randomblob(50) FROM t1;
  INSERT INTO t1 SELECT NULL, randomblob(50) FROM t1;
} -corrupt {


  # Set the page-flags of one of the leaf pages of the index B-Tree to
  # 0x0D (interpreted by SQLite as "leaf page of a table B-Tree").
  #
  set fd [open corrupt.db r+]
  fconfigure $fd -translation binary -encoding binary
  seek $fd [expr 1024*2 + 8] 
  set zRightChild [read $fd 4]
  binary scan $zRightChild I iRightChild
  seek $fd [expr 1024*($iRightChild-1)]
  puts -nonewline $fd "\x0D"
  close $fd
} -test {
  do_test corrupt2-7.1 {
    catchsql { SELECT b FROM t1 ORDER BY b }







































  } {1 {database disk image is malformed}}
}

corruption_test -sqlprep {
  CREATE TABLE t1(a, b, c); CREATE TABLE t8(a, b, c); CREATE TABLE tE(a, b, c);
  CREATE TABLE t2(a, b, c); CREATE TABLE t9(a, b, c); CREATE TABLE tF(a, b, c);
  CREATE TABLE t3(a, b, c); CREATE TABLE tA(a, b, c); CREATE TABLE tG(a, b, c);
................................................................................
  seek $fd 108
  set zRightChild [read $fd 4]
  binary scan $zRightChild I iRightChild
  seek $fd [expr 1024*($iRightChild-1)+3]
  puts -nonewline $fd "\x00\x00"
  close $fd
} -test {
  do_test corrupt2-8.1 {
    catchsql { SELECT sql FROM sqlite_master }
  } {1 {database disk image is malformed}}
}

finish_test







|







 







|










|
>
>













|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|





9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
...
426
427
428
429
430
431
432
433
434
435
436
437
438
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests to make sure SQLite does not crash or
# segfault if it sees a corrupt database file.
#
# $Id: corrupt2.test,v 1.13 2008/07/08 17:13:59 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# The following tests - corrupt2-1.* - create some databases corrupted in
# specific ways and ensure that SQLite detects them as corrupt.
#
................................................................................
        COMMIT;
      }
    } {1 {database disk image is malformed}}
  }
}


set sqlprep {
  PRAGMA page_size = 1024;
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
  CREATE INDEX i1 ON t1(b);
  INSERT INTO t1 VALUES(1, randomblob(50));
  INSERT INTO t1 SELECT NULL, randomblob(50) FROM t1;
  INSERT INTO t1 SELECT NULL, randomblob(50) FROM t1;
  INSERT INTO t1 SELECT NULL, randomblob(50) FROM t1;
  INSERT INTO t1 SELECT NULL, randomblob(50) FROM t1;
  INSERT INTO t1 SELECT NULL, randomblob(50) FROM t1;
  INSERT INTO t1 SELECT NULL, randomblob(50) FROM t1;
}

corruption_test -sqlprep $sqlprep -corrupt {
  # Set the page-flags of one of the leaf pages of the index B-Tree to
  # 0x0D (interpreted by SQLite as "leaf page of a table B-Tree").
  #
  set fd [open corrupt.db r+]
  fconfigure $fd -translation binary -encoding binary
  seek $fd [expr 1024*2 + 8] 
  set zRightChild [read $fd 4]
  binary scan $zRightChild I iRightChild
  seek $fd [expr 1024*($iRightChild-1)]
  puts -nonewline $fd "\x0D"
  close $fd
} -test {
  do_test corrupt2-7.1 {
    catchsql { SELECT b FROM t1 ORDER BY b ASC }
  } {1 {database disk image is malformed}}
}

corruption_test -sqlprep $sqlprep -corrupt {
  # Mess up the page-header of one of the leaf pages of the index B-Tree.
  # The corruption is detected as part of an OP_Prev opcode.
  #
  set fd [open corrupt.db r+]
  fconfigure $fd -translation binary -encoding binary
  seek $fd [expr 1024*2 + 12] 
  set zCellOffset [read $fd 2]
  binary scan $zCellOffset S iCellOffset
  seek $fd [expr 1024*2 + $iCellOffset]
  set zChild [read $fd 4]
  binary scan $zChild I iChild
  seek $fd [expr 1024*($iChild-1)+3]
  puts -nonewline $fd "\xFFFF"
  close $fd
} -test {
  do_test corrupt2-7.1 {
    catchsql { SELECT b FROM t1 ORDER BY b DESC }
  } {1 {database disk image is malformed}}
}

corruption_test -sqlprep $sqlprep -corrupt {
  # Set the page-flags of one of the leaf pages of the table B-Tree to
  # 0x0A (interpreted by SQLite as "leaf page of an index B-Tree").
  #
  set fd [open corrupt.db r+]
  fconfigure $fd -translation binary -encoding binary
  seek $fd [expr 1024*1 + 8] 
  set zRightChild [read $fd 4]
  binary scan $zRightChild I iRightChild
  seek $fd [expr 1024*($iRightChild-1)]
  puts -nonewline $fd "\x0A"
  close $fd
} -test {
  do_test corrupt2-8.1 {
    catchsql { SELECT * FROM t1 WHERE rowid=1000 }
  } {1 {database disk image is malformed}}
}

corruption_test -sqlprep {
  CREATE TABLE t1(a, b, c); CREATE TABLE t8(a, b, c); CREATE TABLE tE(a, b, c);
  CREATE TABLE t2(a, b, c); CREATE TABLE t9(a, b, c); CREATE TABLE tF(a, b, c);
  CREATE TABLE t3(a, b, c); CREATE TABLE tA(a, b, c); CREATE TABLE tG(a, b, c);
................................................................................
  seek $fd 108
  set zRightChild [read $fd 4]
  binary scan $zRightChild I iRightChild
  seek $fd [expr 1024*($iRightChild-1)+3]
  puts -nonewline $fd "\x00\x00"
  close $fd
} -test {
  do_test corrupt2-9.1 {
    catchsql { SELECT sql FROM sqlite_master }
  } {1 {database disk image is malformed}}
}

finish_test

Changes to test/ioerr.test.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
301
302
303
304
305
306
307























308
309
310
# This file implements regression tests for SQLite library.  The
# focus of this file is testing for correct handling of I/O errors
# such as writes failing because the disk is full.
# 
# The tests in this file use special facilities that are only
# available in the SQLite test fixture.
#
# $Id: ioerr.test,v 1.38 2008/07/08 10:19:58 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# If SQLITE_DEFAULT_AUTOVACUUM is set to true, then a simulated IO error
# on the 8th IO operation in the SQL script below doesn't report an error.
#
................................................................................
     DELETE FROM t1 WHERE rowid = 3;
     PRAGMA incremental_vacuum = 2;
     DELETE FROM t1 WHERE rowid = 1;
  } -sqlbody {
     PRAGMA incremental_vacuum = 1;
  }
}
























finish_test








|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
# This file implements regression tests for SQLite library.  The
# focus of this file is testing for correct handling of I/O errors
# such as writes failing because the disk is full.
# 
# The tests in this file use special facilities that are only
# available in the SQLite test fixture.
#
# $Id: ioerr.test,v 1.39 2008/07/08 17:13:59 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# If SQLITE_DEFAULT_AUTOVACUUM is set to true, then a simulated IO error
# on the 8th IO operation in the SQL script below doesn't report an error.
#
................................................................................
     DELETE FROM t1 WHERE rowid = 3;
     PRAGMA incremental_vacuum = 2;
     DELETE FROM t1 WHERE rowid = 1;
  } -sqlbody {
     PRAGMA incremental_vacuum = 1;
  }
}

# Usually, after a new page is allocated from the end of the file, it does
# not need to be written to the journal. The exception is when the new page
# shares its sector with an existing page that does need to be journalled.
# This test case provokes this condition to test for the sake of coverage
# that an IO error while journalling the coresident page is handled correctly.
#
sqlite3_simulate_device -char {} -sectorsize 2048
do_ioerr_test ioerr-12 -ckrefcount true -erc 1 -tclprep {
  db close
  sqlite3 db test.db -vfs devsym

  # Create a test database. Page 2 is the root page of table t1. The only
  # row inserted into t1 has an overflow page - page 3. Page 3 will be
  # coresident on the 2048 byte sector with the next page to be allocated.
  # 
  db eval { PRAGMA page_size = 1024 }
  db eval { CREATE TABLE t1(x) }
  db eval { INSERT INTO t1 VALUES(randomblob(1100)); }
} -tclbody {
  db eval { INSERT INTO t1 VALUES(randomblob(2000)); }
}
sqlite3_simulate_device -char {} -sectorsize 0

finish_test

Changes to test/softheap1.test.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
40
41
42
43
44
45
46

47
48
49
#
#***********************************************************************
# 
# This test script reproduces the problem reported by ticket #2565,
# A database corruption bug that occurs in auto_vacuum mode when
# the soft_heap_limit is set low enough to be triggered.
#
# $Id: softheap1.test,v 1.4 2008/01/19 20:11:26 drh Exp $


set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !integrityck {
  finish_test
................................................................................
  execsql {
    ROLLBACK;
  }
  execsql {
    PRAGMA integrity_check;
  }
} {ok}

sqlite3_soft_heap_limit $soft_limit
   
finish_test







|







 







>



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
40
41
42
43
44
45
46
47
48
49
50
#
#***********************************************************************
# 
# This test script reproduces the problem reported by ticket #2565,
# A database corruption bug that occurs in auto_vacuum mode when
# the soft_heap_limit is set low enough to be triggered.
#
# $Id: softheap1.test,v 1.5 2008/07/08 17:13:59 danielk1977 Exp $


set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !integrityck {
  finish_test
................................................................................
  execsql {
    ROLLBACK;
  }
  execsql {
    PRAGMA integrity_check;
  }
} {ok}

sqlite3_soft_heap_limit $soft_limit
   
finish_test