/ Check-in [270d47e8]
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: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 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
....
1050
1051
1052
1053
1054
1055
1056




1057
1058
1059
1060
1061
1062
1063
....
4087
4088
4089
4090
4091
4092
4093
4094

4095
4096
4097
4098
4099
4100
4101
** 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.453 2008/05/02 14:23:55 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"

................................................................................
  assert( sqlite3_mutex_held(pBt->mutex) );
  if( pgno==0 ){
    return SQLITE_CORRUPT_BKPT; 
  }
  rc = sqlite3BtreeGetPage(pBt, pgno, ppPage, 0);
  if( rc==SQLITE_OK && (*ppPage)->isInit==0 ){
    rc = sqlite3BtreeInitPage(*ppPage, pParent);




  }
  return rc;
}

/*
** Release a MemPage.  This should be called once for each prior
** call to sqlite3BtreeGetPage.
................................................................................
        }

        iPage = get4byte(&aData[8+closest*4]);
        if( !searchList || iPage==nearby ){
          *pPgno = iPage;
          if( *pPgno>sqlite3PagerPagecount(pBt->pPager) ){
            /* Free page off the end of the file */
            return SQLITE_CORRUPT_BKPT;

          }
          TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d"
                 ": %d more free pages\n",
                 *pPgno, closest+1, k, pTrunk->pgno, n-1));
          if( closest<k-1 ){
            memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
          }







|







 







>
>
>
>







 







|
>







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
....
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
** 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.454 2008/05/05 12:09:33 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"

................................................................................
  assert( sqlite3_mutex_held(pBt->mutex) );
  if( pgno==0 ){
    return SQLITE_CORRUPT_BKPT; 
  }
  rc = sqlite3BtreeGetPage(pBt, pgno, ppPage, 0);
  if( rc==SQLITE_OK && (*ppPage)->isInit==0 ){
    rc = sqlite3BtreeInitPage(*ppPage, pParent);
    if( rc!=SQLITE_OK ){
      releasePage(*ppPage);
      *ppPage = 0;
    }
  }
  return rc;
}

/*
** Release a MemPage.  This should be called once for each prior
** call to sqlite3BtreeGetPage.
................................................................................
        }

        iPage = get4byte(&aData[8+closest*4]);
        if( !searchList || iPage==nearby ){
          *pPgno = iPage;
          if( *pPgno>sqlite3PagerPagecount(pBt->pPager) ){
            /* Free page off the end of the file */
            rc = SQLITE_CORRUPT_BKPT;
            goto end_allocate_page;
          }
          TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d"
                 ": %d more free pages\n",
                 *pPgno, closest+1, k, pTrunk->pgno, n-1));
          if( closest<k-1 ){
            memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
          }

Changes to test/corrupt.test.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
106
107
108
109
110
111
112









113
114
115
116
117
118
119
#
#***********************************************************************
# 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: corrupt.test,v 1.8 2005/02/19 08:18:06 danielk1977 Exp $

catch {file delete -force test.db}
catch {file delete -force test.db-journal}

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

................................................................................
    catchsql {DROP TABLE t1}
    set x {}
  } {}
  do_test corrupt-2.$tn.7 {
    catchsql {PRAGMA integrity_check}
    set x {}
  } {}









}  

#------------------------------------------------------------------------
# For these tests, swap the rootpage entries of t1 (a table) and t1i1 (an
# index on t1) in sqlite_master. Then perform a few different queries
# and make sure this is detected as corruption.
#







|







 







>
>
>
>
>
>
>
>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#
#***********************************************************************
# 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: corrupt.test,v 1.9 2008/05/05 12:09:33 danielk1977 Exp $

catch {file delete -force test.db}
catch {file delete -force test.db-journal}

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

................................................................................
    catchsql {DROP TABLE t1}
    set x {}
  } {}
  do_test corrupt-2.$tn.7 {
    catchsql {PRAGMA integrity_check}
    set x {}
  } {}

  # Check that no page references were leaked.
  do_test corrupt-2.$tn.8 {
    set bt [btree_from_db db]
    db_enter db
    array set stats [btree_pager_stats $bt]
    db_leave db
    set stats(ref)
  } {0}
}  

#------------------------------------------------------------------------
# For these tests, swap the rootpage entries of t1 (a table) and t1i1 (an
# index on t1) in sqlite_master. Then perform a few different queries
# and make sure this is detected as corruption.
#