]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Make SQLITE_CORRUPT sticky: If a CORRUPT error is returned, all subsequent
authordrh <>
Wed, 10 Nov 2021 10:59:10 +0000 (10:59 +0000)
committerdrh <>
Wed, 10 Nov 2021 10:59:10 +0000 (10:59 +0000)
write statements within the same transaction also fail early with
SQLITE_CORRUPT.

FossilOrigin-Name: 3feb0f1c3840904d28fc9a61262820e2b9b764addc1dd178aecc2cd0f952042c

manifest
manifest.uuid
src/btree.c
src/main.c
src/sqliteInt.h
src/vdbe.c

index 944f5f2d29587b071d1d4022a1c2dc61c80c4978..f23b2c55dd3891b7e021ec7a0751cc652a480ee2 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Change\stest\scase\serror\smessage\stext\sto\smatch\sthe\scurrent\simplementation.
-D 2021-11-09T13:31:42.748
+C Make\sSQLITE_CORRUPT\ssticky:\s\sIf\sa\sCORRUPT\serror\sis\sreturned,\sall\ssubsequent\nwrite\sstatements\swithin\sthe\ssame\stransaction\salso\sfail\searly\swith\nSQLITE_CORRUPT.
+D 2021-11-10T10:59:10.748
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -491,7 +491,7 @@ F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf
 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d
 F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d
 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
-F src/btree.c 2c8a52a7fd84b1aec4a79e7861b6368aecbf011a43247cc7d9a2946c7f0ae5ea
+F src/btree.c 6fd5c54a2edec870a0ba0c2c8b28577bf587e05a6f183da6febe09e3700ded6f
 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22
 F src/btreeInt.h ee9348c4cb9077243b049edc93a82c1f32ca48baeabf2140d41362b9f9139ff7
 F src/build.c 1b41a6417e5bb260a5988588764863229905b07b3e9a47878030a1c92d49010f
@@ -514,7 +514,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
 F src/insert.c 7fcbbe9114ac402ea3c0c6a3810f13fc89cae8131ea1659ec472be7caac10192
 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
 F src/loadext.c e1dcff1c916bf6834e150b492eddda5d9792453182d2ad64294d2266b6e93c4c
-F src/main.c 5ed1babdec5bbf935fb4586fcb12debbff760c301948ac46cf90e720b4405a8b
+F src/main.c 7bd4fdc41ef53535271a1816ff043ba153cda03842b444b6e2f57b27b2cb9090
 F src/malloc.c ef796bcc0e81d845d59a469f1cf235056caf9024172fd524e32136e65593647b
 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
@@ -555,7 +555,7 @@ F src/shell.c.in f8854bcb0d14707d661732698d5210d7f01694000c46e8014b323ad18f575be
 F src/sqlite.h.in 5cd209ac7dc4180f0e19292846f40440b8488015849ca0110c70b906b57d68f0
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 8ff2fd2c166150b2e48639f5e506fb44e29f1a3f65031710b9e89d1c126ac839
-F src/sqliteInt.h 8e770859062a87254dabd183b3f7bd29f89fd5905515beac00877958e88e06ce
+F src/sqliteInt.h c36cdf01fcd624f9988305158e89bf1d7246b3a05f0fe578bc7dd2507e53e59d
 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1
 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@@ -622,7 +622,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937
 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
 F src/util.c 30df8356e231dad33be10bb27897655002668343280004ba28c734489414a167
 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3
-F src/vdbe.c f2b30e312d2dc69d429998f17fab74298a4d9ed8c6d57c0d23d0284414c6ea1b
+F src/vdbe.c 34a0bc8b9e934523fd528885689334821d7a1d7048e739a32801a810ac848c39
 F src/vdbe.h 25dabb25c7e157b84e59260cfb5b466c3ac103ede9f36f4db371332c47601abe
 F src/vdbeInt.h 31fbabdc1ed61d9695337dfe5269ea94e1cf615c17f5cafeaa1bb01066820bab
 F src/vdbeapi.c f4bd14b42d9717a35baac5f20c0c4bfccbf3691d64dc6ec02fc0ef19374d3c92
@@ -1932,7 +1932,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P ba4fb51853fbcb8c142a350b4db0d59153f28ba0a63ad9a2d6fea7096d3dd544
-R 53a575150d86630b94dc195691567d17
+P de10795a1cf70925088e9652998e813665b2e147ffa4a4edab18c7e2c66bf5ae
+R e127d9e9bc185c201fc0d430c0552522
 U drh
-Z 2471e2a59037263eea8aada9ef5e2a3c
+Z 644a270e60b1b5e3bf9aa34104968aa1
index 72257e642dfcaf711af9484778533bf4a37a3d06..ec8cdc26adecb5f32aef6ea2ceeafb29bceebf88 100644 (file)
@@ -1 +1 @@
-de10795a1cf70925088e9652998e813665b2e147ffa4a4edab18c7e2c66bf5ae
\ No newline at end of file
+3feb0f1c3840904d28fc9a61262820e2b9b764addc1dd178aecc2cd0f952042c
\ No newline at end of file
index 67611c3bf5fc561722ebad086370a1bada98c487..49f80b5b39ac39362147a286316fcf08fea8c42e 100644 (file)
@@ -1488,7 +1488,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
           if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage);
           memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
           sz += sz2;
-        }else if( iFree+sz>usableSize ){
+        }else if( NEVER(iFree+sz>usableSize) ){
           return SQLITE_CORRUPT_PAGE(pPage);
         }
 
@@ -7111,7 +7111,7 @@ static int rebuildPage(
 
   assert( i<iEnd );
   j = get2byte(&aData[hdr+5]);
-  if( j>(u32)usableSize ){ j = 0; }
+  if( NEVER(j>(u32)usableSize) ){ j = 0; }
   memcpy(&pTmp[j], &aData[j], usableSize - j);
 
   for(k=0; pCArray->ixNx[k]<=i && ALWAYS(k<NB*2); k++){}
@@ -8747,7 +8747,7 @@ static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){
   do{
     rc = btreeGetPage(pBt, ovflPgno, &pPage, 0);
     if( rc ) return rc;
-    if( sqlite3PagerPageRefcount(pPage->pDbPage)!=1 || pPage->isInit ){
+    if( sqlite3PagerPageRefcount(pPage->pDbPage)!=1 || NEVER(pPage->isInit) ){
       rc = SQLITE_CORRUPT_BKPT;
     }else{
       if( iOffset+ovflPageSize<(u32)nTotal ){
index 7eb42f7ae492d805d5504149cabf2090ef422acf..4b2d0592c9c56ee23483a9332881c83173dabd44 100644 (file)
@@ -1460,7 +1460,7 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){
   /* Any deferred constraint violations have now been resolved. */
   db->nDeferredCons = 0;
   db->nDeferredImmCons = 0;
-  db->flags &= ~(u64)SQLITE_DeferFKs;
+  db->flags &= ~(u64)(SQLITE_DeferFKs|SQLITE_CorruptRdOnly);
 
   /* If one has been configured, invoke the rollback-hook callback */
   if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
index 75f3bfca2d65a5ee13f26472fe1ec6da442b46f7..cece2360e8a1429c529b360a594d7295dce67504 100644 (file)
@@ -1712,6 +1712,7 @@ struct sqlite3 {
 #define SQLITE_CountRows      HI(0x00001) /* Count rows changed by INSERT, */
                                           /*   DELETE, or UPDATE and return */
                                           /*   the count using a callback. */
+#define SQLITE_CorruptRdOnly  HI(0x00002) /* Prohibit writes due to error */
 
 /* Flags used only if debugging */
 #ifdef SQLITE_DEBUG
index 5b794ff9424edb7c1c12c1696166b1deb51d9427..b2390e05672ea0bce10179a1b3f05d8a62c93652 100644 (file)
@@ -3604,6 +3604,7 @@ case OP_AutoCommit: {
     sqlite3CloseSavepoints(db);
     if( p->rc==SQLITE_OK ){
       rc = SQLITE_DONE;
+      if( db->autoCommit ) db->flags &= ~SQLITE_CorruptRdOnly;
     }else{
       rc = SQLITE_ERROR;
     }
@@ -3665,8 +3666,15 @@ case OP_Transaction: {
   assert( pOp->p1>=0 && pOp->p1<db->nDb );
   assert( DbMaskTest(p->btreeMask, pOp->p1) );
   assert( rc==SQLITE_OK );
-  if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){
-    rc = SQLITE_READONLY;
+  if( pOp->p2 && (db->flags & (SQLITE_QueryOnly|SQLITE_CorruptRdOnly))!=0 ){
+    if( db->flags & SQLITE_QueryOnly ){
+      /* Writes prohibited by the "PRAGMA query_only=TRUE" statement */
+      rc = SQLITE_READONLY;
+    }else{
+      /* Writes prohibited due to a prior SQLITE_CORRUPT in the current
+      ** transaction */
+      rc = SQLITE_CORRUPT;
+    }
     goto abort_due_to_error;
   }
   pBt = db->aDb[pOp->p1].pBt;
@@ -8391,6 +8399,9 @@ abort_due_to_error:
                    (int)(pOp - aOp), p->zSql, p->zErrMsg);
   sqlite3VdbeHalt(p);
   if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db);
+  if( rc==SQLITE_CORRUPT && db->autoCommit==0 ){
+    db->flags |= SQLITE_CorruptRdOnly;
+  }
   rc = SQLITE_ERROR;
   if( resetSchemaOnFault>0 ){
     sqlite3ResetOneSchema(db, resetSchemaOnFault-1);