/ Check-in [c8e85fff]
Login

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

Overview
Comment:Fix a segfault that could occur while attempting to add new pages to the freelist in a corrupt database. (CVS 4414)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:c8e85fff7ede68f0b8c8ebfe3df4b26a630abeff
User & Date: drh 2007-09-07 14:32:07
Context
2007-09-07
18:40
Modify test_thread.c to use tcl apis for creating threads. (CVS 4415) check-in: 9b7bab7f user: danielk1977 tags: trunk
14:32
Fix a segfault that could occur while attempting to add new pages to the freelist in a corrupt database. (CVS 4414) check-in: c8e85fff user: drh tags: trunk
11:29
Add the beginning of the thread-safety tests. There are more to come. (CVS 4413) check-in: 753908e8 user: danielk1977 tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

     5      5   ** a legal notice, here is a blessing:
     6      6   **
     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12         -** $Id: btree.c,v 1.424 2007/09/06 23:39:37 drh Exp $
           12  +** $Id: btree.c,v 1.425 2007/09/07 14:32:07 drh Exp $
    13     13   **
    14     14   ** This file implements a external (disk-based) database using BTrees.
    15     15   ** See the header comment on "btreeInt.h" for additional information.
    16     16   ** Including a description of file format and an overview of operation.
    17     17   */
    18     18   #include "btreeInt.h"
    19     19   
................................................................................
  4136   4136       rc = sqlite3BtreeGetPage(pBt, get4byte(&pPage1->aData[32]), &pTrunk, 0);
  4137   4137       if( rc ) return rc;
  4138   4138       k = get4byte(&pTrunk->aData[4]);
  4139   4139       if( k>=pBt->usableSize/4 - 8 ){
  4140   4140         /* The trunk is full.  Turn the page being freed into a new
  4141   4141         ** trunk page with no leaves. */
  4142   4142         rc = sqlite3PagerWrite(pPage->pDbPage);
  4143         -      if( rc ) return rc;
  4144         -      put4byte(pPage->aData, pTrunk->pgno);
  4145         -      put4byte(&pPage->aData[4], 0);
  4146         -      put4byte(&pPage1->aData[32], pPage->pgno);
  4147         -      TRACE(("FREE-PAGE: %d new trunk page replacing %d\n",
  4148         -              pPage->pgno, pTrunk->pgno));
         4143  +      if( rc==SQLITE_OK ){
         4144  +        put4byte(pPage->aData, pTrunk->pgno);
         4145  +        put4byte(&pPage->aData[4], 0);
         4146  +        put4byte(&pPage1->aData[32], pPage->pgno);
         4147  +        TRACE(("FREE-PAGE: %d new trunk page replacing %d\n",
         4148  +                pPage->pgno, pTrunk->pgno));
         4149  +      }
         4150  +    }else if( k<0 ){
         4151  +      rc = SQLITE_CORRUPT;
  4149   4152       }else{
  4150   4153         /* Add the newly freed page as a leaf on the current trunk */
  4151   4154         rc = sqlite3PagerWrite(pTrunk->pDbPage);
  4152   4155         if( rc==SQLITE_OK ){
  4153   4156           put4byte(&pTrunk->aData[4], k+1);
  4154   4157           put4byte(&pTrunk->aData[8+k*4], pPage->pgno);
  4155   4158   #ifndef SQLITE_SECURE_DELETE

Added test/corrupt4.test.

            1  +# 2007 Sept 7
            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  +# This file implements regression tests for SQLite library.
           12  +#
           13  +# This file implements tests to make sure SQLite does not crash or
           14  +# segfault if it sees a corrupt database file.
           15  +#
           16  +# $Id: corrupt4.test,v 1.1 2007/09/07 14:32:07 drh Exp $
           17  +
           18  +set testdir [file dirname $argv0]
           19  +source $testdir/tester.tcl
           20  +
           21  +# We must have the page_size pragma for these tests to work.
           22  +#
           23  +ifcapable !pager_pragmas {
           24  +  finish_test
           25  +  return
           26  +}
           27  +
           28  +# Create a database with a freelist containing at least two pages.
           29  +#
           30  +do_test corrupt4-1.1 {
           31  +  set bigstring [string repeat 0123456789 200]
           32  +  execsql {
           33  +    PRAGMA auto_vacuum=OFF;
           34  +    PRAGMA page_size=1024;
           35  +    CREATE TABLE t1(x);
           36  +    INSERT INTO t1 VALUES($bigstring);
           37  +    CREATE TABLE t2(y);
           38  +    INSERT INTO t2 VALUES(1);
           39  +    DROP TABLE t1;
           40  +  }
           41  +  file size test.db
           42  +} [expr {1024*4}]
           43  +
           44  +# Verify that there are two pages on the freelist.
           45  +#
           46  +do_test corrupt4-1.2 {
           47  +  execsql {PRAGMA freelist_count}
           48  +} {2}
           49  +
           50  +# Get the page number for the trunk of the freelist.
           51  +#
           52  +set trunkpgno [hexio_get_int [hexio_read test.db 32 4]]
           53  +set baseaddr [expr {($trunkpgno-1)*1024}]
           54  +
           55  +# Verify that the trunk of the freelist has exactly one
           56  +# leaf.
           57  +#
           58  +do_test corrupt4-1.3 {
           59  +  hexio_get_int [hexio_read test.db [expr {$::baseaddr+4}] 4]
           60  +} {1}
           61  +
           62  +# Insert a negative number as the number of leaves on the trunk.
           63  +# Then try to add a new element to the freelist.
           64  +#
           65  +do_test corrupt4-1.4 {
           66  +  hexio_write test.db [expr {$::baseaddr+4}] [hexio_render_int32 -100000000]
           67  +  db close
           68  +  sqlite3 db test.db
           69  +  catchsql {
           70  +    DROP TABLE t2
           71  +  }
           72  +} {1 {database disk image is malformed}}
           73  +
           74  +finish_test