/ Check-in [270d47e8]
Login

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

Overview
Comment:Avoid leaking page references when database corruption is encountered. (CVS 5080)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 270d47e8d0a20868879a95b66cb547e1e5b642d9
User & Date: danielk1977 2008-05-05 12:09:33
Context
2008-05-05
13:23
Fix a couple of minor problems with transactions in virtual tables. (CVS 5081) check-in: 2275fc6e user: drh tags: trunk
12:09
Avoid leaking page references when database corruption is encountered. (CVS 5080) check-in: 270d47e8 user: danielk1977 tags: trunk
11:33
Fix to test code to build when ENABLE_IOTRACE is not defined. (CVS 5079) check-in: 8fa2bda4 user: danielk1977 tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes 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.453 2008/05/02 14:23:55 drh Exp $
           12  +** $Id: btree.c,v 1.454 2008/05/05 12:09:33 danielk1977 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   
................................................................................
  1050   1050     assert( sqlite3_mutex_held(pBt->mutex) );
  1051   1051     if( pgno==0 ){
  1052   1052       return SQLITE_CORRUPT_BKPT; 
  1053   1053     }
  1054   1054     rc = sqlite3BtreeGetPage(pBt, pgno, ppPage, 0);
  1055   1055     if( rc==SQLITE_OK && (*ppPage)->isInit==0 ){
  1056   1056       rc = sqlite3BtreeInitPage(*ppPage, pParent);
         1057  +    if( rc!=SQLITE_OK ){
         1058  +      releasePage(*ppPage);
         1059  +      *ppPage = 0;
         1060  +    }
  1057   1061     }
  1058   1062     return rc;
  1059   1063   }
  1060   1064   
  1061   1065   /*
  1062   1066   ** Release a MemPage.  This should be called once for each prior
  1063   1067   ** call to sqlite3BtreeGetPage.
................................................................................
  4087   4091           }
  4088   4092   
  4089   4093           iPage = get4byte(&aData[8+closest*4]);
  4090   4094           if( !searchList || iPage==nearby ){
  4091   4095             *pPgno = iPage;
  4092   4096             if( *pPgno>sqlite3PagerPagecount(pBt->pPager) ){
  4093   4097               /* Free page off the end of the file */
  4094         -            return SQLITE_CORRUPT_BKPT;
         4098  +            rc = SQLITE_CORRUPT_BKPT;
         4099  +            goto end_allocate_page;
  4095   4100             }
  4096   4101             TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d"
  4097   4102                    ": %d more free pages\n",
  4098   4103                    *pPgno, closest+1, k, pTrunk->pgno, n-1));
  4099   4104             if( closest<k-1 ){
  4100   4105               memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
  4101   4106             }

Changes to test/corrupt.test.

     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.
    12     12   #
    13     13   # This file implements tests to make sure SQLite does not crash or
    14     14   # segfault if it sees a corrupt database file.
    15     15   #
    16         -# $Id: corrupt.test,v 1.8 2005/02/19 08:18:06 danielk1977 Exp $
           16  +# $Id: corrupt.test,v 1.9 2008/05/05 12:09:33 danielk1977 Exp $
    17     17   
    18     18   catch {file delete -force test.db}
    19     19   catch {file delete -force test.db-journal}
    20     20   
    21     21   set testdir [file dirname $argv0]
    22     22   source $testdir/tester.tcl
    23     23   
................................................................................
   106    106       catchsql {DROP TABLE t1}
   107    107       set x {}
   108    108     } {}
   109    109     do_test corrupt-2.$tn.7 {
   110    110       catchsql {PRAGMA integrity_check}
   111    111       set x {}
   112    112     } {}
          113  +
          114  +  # Check that no page references were leaked.
          115  +  do_test corrupt-2.$tn.8 {
          116  +    set bt [btree_from_db db]
          117  +    db_enter db
          118  +    array set stats [btree_pager_stats $bt]
          119  +    db_leave db
          120  +    set stats(ref)
          121  +  } {0}
   113    122   }  
   114    123   
   115    124   #------------------------------------------------------------------------
   116    125   # For these tests, swap the rootpage entries of t1 (a table) and t1i1 (an
   117    126   # index on t1) in sqlite_master. Then perform a few different queries
   118    127   # and make sure this is detected as corruption.
   119    128   #