]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Further modifications to new code to better handle corrupt databases.
authordan <dan@noemail.net>
Sat, 25 Oct 2014 20:36:28 +0000 (20:36 +0000)
committerdan <dan@noemail.net>
Sat, 25 Oct 2014 20:36:28 +0000 (20:36 +0000)
FossilOrigin-Name: 1a8cf0a043347772ac54d150d634c32845beee8b

manifest
manifest.uuid
src/btree.c

index 6c0464217bc7e70f622a951d8831b0e6632293b5..1a5be4bf57742dc1220fd50fc7a50233da92a9cd 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Ensure\sthat\sthe\s"Any\sprior\scache\sentry\sassociated\swith\snewKey\sis\sguaranteed\snot\sto\sbe\spinned"\sguarantee\smade\sto\sxRekey\simplementations\sis\snot\sviolated.
-D 2014-10-24T20:57:03.500
+C Further\smodifications\sto\snew\scode\sto\sbetter\shandle\scorrupt\sdatabases.
+D 2014-10-25T20:36:28.557
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -172,7 +172,7 @@ F src/auth.c d8abcde53426275dab6243b441256fcd8ccbebb2
 F src/backup.c a31809c65623cc41849b94d368917f8bb66e6a7e
 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
 F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5
-F src/btree.c 4decfb3b97d16afdd0e5a7e5f876af1f528e8a69
+F src/btree.c 2639b89f6728f5775044704c7757c0226e071bd1
 F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8
 F src/btreeInt.h 026d0129724e8f265fdc60d44ec240cf5a4e6179
 F src/build.c 9dc2bd94347b878c89627000c92b0c8d97ec2919
@@ -1205,7 +1205,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 19736dd9fbbb7e252c4f8715e2277d48ac41f5bc
-R c9d1872515b77329bc9fbfe4c8e91668
+P ecc3544e712041736af7c7b4f34864a1f2e30ff7
+R 17dc589efbb3f16f6448c9d9d1ae2e24
 U dan
-Z 931e363227b1144b3ac19bee87a82036
+Z c615066e82cbd286f5597ce396069fd7
index 470b2345ea12afa36c38d7800688ef28b998bef2..23643921ecae106b30ff97c874367ff4931480e5 100644 (file)
@@ -1 +1 @@
-ecc3544e712041736af7c7b4f34864a1f2e30ff7
\ No newline at end of file
+1a8cf0a043347772ac54d150d634c32845beee8b
\ No newline at end of file
index 83ed66414c1b989c29dd64efa0d7eb5dcde23001..46ce39abc7ed994e3246337debaf83c8ef2380d2 100644 (file)
@@ -6099,6 +6099,7 @@ static int pageFreeArray(
 ){
   u8 * const aData = pPg->aData;
   u8 * const pEnd = &aData[pPg->pBt->usableSize];
+  u8 * const pStart = &aData[pPg->hdrOffset + 8 + pPg->childPtrSize];
   int nRet = 0;
   int i;
   u8 *pFree = 0;
@@ -6106,12 +6107,13 @@ static int pageFreeArray(
 
   for(i=0; i<nCell; i++){
     u8 *pCell = apCell[i];
-    if( pCell>aData && pCell<pEnd ){
+    if( pCell>=pStart && pCell<pEnd ){
       int sz = szCell[i];
       if( pFree!=(pCell + sz) ){
         if( pFree ) freeSpace(pPg, pFree - aData, szFree);
         pFree = pCell;
         szFree = sz;
+        if( pFree+sz>pEnd ) return 0;
       }else{
         pFree = pCell;
         szFree += sz;
@@ -6854,6 +6856,18 @@ static int balance_nonroot(
   for(i=0; i<nNew; i++){
     aPgno[i] = apNew[i]->pgno;
     aPgFlags[i] = apNew[i]->pDbPage->flags;
+    for(j=0; j<i; j++){
+      if( aPgno[j]==aPgno[i] ){
+        /* This branch is taken if the set of sibling pages somehow contains
+        ** duplicate entries. This can happen if the database is corrupt. 
+        ** It would be simpler to detect this as part of the loop below, but
+        ** in order to avoid populating the pager cache with two separate
+        ** objects associated with the same page number.  */
+        assert( CORRUPT_DB );
+        rc = SQLITE_CORRUPT_BKPT;
+        goto balance_cleanup;
+      }
+    }
   }
   for(i=0; i<nNew; i++){
     int iBest = 0;                /* aPgno[] index of page number to use */
@@ -7062,12 +7076,14 @@ static int balance_nonroot(
     ** is important if the parent page happens to be page 1 of the database
     ** image.  */
     assert( nNew==1 );
-    defragmentPage(apNew[0]);
-    assert( apNew[0]->nFree == 
-        (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2) 
-    );
-    copyNodeContent(apNew[0], pParent, &rc);
-    freePage(apNew[0], &rc);
+    rc = defragmentPage(apNew[0]);
+    if( rc==SQLITE_OK ){
+      assert( apNew[0]->nFree == 
+          (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2)
+      );
+      copyNodeContent(apNew[0], pParent, &rc);
+      freePage(apNew[0], &rc);
+    }
   }else if( ISAUTOVACUUM && !leafCorrection ){
     /* Fix the pointer map entries associated with the right-child of each
     ** sibling page. All other pointer map entries have already been taken