]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Candidate fix for ticket [6bfb98dfc0c]: Make sure invalid cursors drop all
authordrh <drh@noemail.net>
Wed, 27 Mar 2013 03:15:23 +0000 (03:15 +0000)
committerdrh <drh@noemail.net>
Wed, 27 Mar 2013 03:15:23 +0000 (03:15 +0000)
references to database pages prior to doing any insert or update.

FossilOrigin-Name: 322a5f086d9ee46017f750df81527799a54ae258

manifest
manifest.uuid
src/btree.c
test/tkt-6bfb98dfc0.test [new file with mode: 0644]

index abc6aa243070c37b4587c114d88f7c16da03121e..007356f17667d06a34f56e457da07ebbce367332 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sa\ssecond\stest\sfor\s[38b1ae018f].
-D 2013-03-25T12:02:45.865
+C Candidate\sfix\sfor\sticket\s[6bfb98dfc0c]:\sMake\ssure\sinvalid\scursors\sdrop\sall\nreferences\sto\sdatabase\spages\sprior\sto\sdoing\sany\sinsert\sor\supdate.
+D 2013-03-27T03:15:23.329
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in df3e48659d80e1b7765785d8d66c86b320f72cc7
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -121,7 +121,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
 F src/backup.c b2cac9f7993f3f9588827b824b1501d0c820fa68
 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
 F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
-F src/btree.c 3cebaa69db81a528e115b463a5506133a0043710
+F src/btree.c 62ba5954765efc711c873a20a53f60d9fc2843ba
 F src/btree.h 3ad7964d6c5b1c7bff569aab6adfa075f8bf06cd
 F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2
 F src/build.c 083da8466fd7e481cb8bd5264398f537507f6176
@@ -784,6 +784,7 @@ F test/tkt-54844eea3f.test a12b851128f46a695e4e378cca67409b9b8f5894
 F test/tkt-5d863f876e.test c9f36ca503fa154a3655f92a69d2c30da1747bfa
 F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84
 F test/tkt-5ee23731f.test 9db6e1d7209dc0794948b260d6f82b2b1de83a9f
+F test/tkt-6bfb98dfc0.test 24780633627b5cfc0635a5500c2389ebfb563336
 F test/tkt-752e1646fc.test ea78d88d14fe9866bdd991c634483334639e13bf
 F test/tkt-78e04e52ea.test 703e0bfb23d543edf0426a97e3bbd0ca346508ec
 F test/tkt-7a31705a7e6.test 5a7889fdb095ffbe1622413e0145de1637d421bd
@@ -1039,7 +1040,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
-P f85f9103cffa5c8ba6a63a68beb90817147ba080
-R 8636831e10a59eea94894795b6da6922
-U dan
-Z 40d326d8e18513e2868148c4279af040
+P 5062db672c00c3365d51cd6b39815078f5b6b525
+R 444ec66222f6e3876b5a1bc78bf6602c
+U drh
+Z 3d135e15ecdab16eb6decd45c9d13940
index 14d19b23d153829526f4e71ca25b248e803bda1f..ed40effb49f51a1a73d71b5884e1772114693f7c 100644 (file)
@@ -1 +1 @@
-5062db672c00c3365d51cd6b39815078f5b6b525
\ No newline at end of file
+322a5f086d9ee46017f750df81527799a54ae258
\ No newline at end of file
index b3549fa697ea18c1de98692133d499f4b800d34e..96140d68c63e21daa47d531ef0831bf52d18a66a 100644 (file)
@@ -575,6 +575,19 @@ static void btreeClearHasContent(BtShared *pBt){
   pBt->pHasContent = 0;
 }
 
+/*
+** Release all of the apPage[] pages for a cursor.
+*/
+static void btreeReleaseAllCursorPages(BtCursor *pCur){
+  int i;
+  for(i=0; i<=pCur->iPage; i++){
+    releasePage(pCur->apPage[i]);
+    pCur->apPage[i] = 0;
+  }
+  pCur->iPage = -1;
+}
+
+
 /*
 ** Save the current cursor position in the variables BtCursor.nKey 
 ** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK.
@@ -614,12 +627,7 @@ static int saveCursorPosition(BtCursor *pCur){
   assert( !pCur->apPage[0]->intKey || !pCur->pKey );
 
   if( rc==SQLITE_OK ){
-    int i;
-    for(i=0; i<=pCur->iPage; i++){
-      releasePage(pCur->apPage[i]);
-      pCur->apPage[i] = 0;
-    }
-    pCur->iPage = -1;
+    btreeReleaseAllCursorPages(pCur);
     pCur->eState = CURSOR_REQUIRESEEK;
   }
 
@@ -637,11 +645,15 @@ static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
   assert( sqlite3_mutex_held(pBt->mutex) );
   assert( pExcept==0 || pExcept->pBt==pBt );
   for(p=pBt->pCursor; p; p=p->pNext){
-    if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) && 
-        p->eState==CURSOR_VALID ){
-      int rc = saveCursorPosition(p);
-      if( SQLITE_OK!=rc ){
-        return rc;
+    if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){
+      if( p->eState==CURSOR_VALID ){
+        int rc = saveCursorPosition(p);
+        if( SQLITE_OK!=rc ){
+          return rc;
+        }
+      }else{
+        testcase( p->iPage>0 );
+        btreeReleaseAllCursorPages(p);
       }
     }
   }
diff --git a/test/tkt-6bfb98dfc0.test b/test/tkt-6bfb98dfc0.test
new file mode 100644 (file)
index 0000000..675a3fc
--- /dev/null
@@ -0,0 +1,61 @@
+# 2013 March 27
+#
+# The author disclaims copyright to this source code.  In place of
+# 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.
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library. Specifically,
+# it tests that ticket [6bfb98dfc0]
+#
+# The final INSERT in the script below reports that the database is
+# corrupt (SQLITE_CORRUPT) and aborts even though the database is not
+# corrupt.
+#
+#    PRAGMA page_size=512;
+#    CREATE TABLE t1(x INTEGER PRIMARY KEY, y);
+#    INSERT INTO t1 VALUES(1,randomblob(400));
+#    INSERT INTO t1 VALUES(2,randomblob(400));
+#    INSERT INTO t1 SELECT x+2, randomblob(400) FROM t1;
+#    INSERT INTO t1 SELECT x+4, randomblob(400) FROM t1;
+#    INSERT INTO t1 SELECT x+8, randomblob(400) FROM t1;
+#    INSERT INTO t1 SELECT x+16, randomblob(400) FROM t1;
+#    INSERT INTO t1 SELECT x+32, randomblob(400) FROM t1;
+#    INSERT INTO t1 SELECT x+64, randomblob(400) FROM t1 WHERE x<10;
+#    CREATE TRIGGER r1 AFTER INSERT ON t1 WHEN new.x=74 BEGIN
+#      DELETE FROM t1;
+#      INSERT INTO t1 VALUES(75, randomblob(400));
+#      INSERT INTO t1 VALUES(76, randomblob(400));
+#    END;
+#    INSERT INTO t1 VALUES(74, randomblob(400));
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+do_test tkt-6bfb98dfc0.100 {
+  db eval {
+    PRAGMA page_size=512;
+    CREATE TABLE t1(x INTEGER PRIMARY KEY, y);
+    INSERT INTO t1 VALUES(1,randomblob(400));
+    INSERT INTO t1 VALUES(2,randomblob(400));
+    INSERT INTO t1 SELECT x+2, randomblob(400) FROM t1;
+    INSERT INTO t1 SELECT x+4, randomblob(400) FROM t1;
+    INSERT INTO t1 SELECT x+8, randomblob(400) FROM t1;
+    INSERT INTO t1 SELECT x+16, randomblob(400) FROM t1;
+    INSERT INTO t1 SELECT x+32, randomblob(400) FROM t1;
+    INSERT INTO t1 SELECT x+64, randomblob(400) FROM t1 WHERE x<10;
+    CREATE TRIGGER r1 AFTER INSERT ON t1 WHEN new.x=74 BEGIN
+      DELETE FROM t1;
+      INSERT INTO t1 VALUES(75, randomblob(400));
+      INSERT INTO t1 VALUES(76, randomblob(400));
+    END;
+    INSERT INTO t1 VALUES(74, randomblob(400));
+    SELECT x, length(y) FROM t1 ORDER BY x;
+  }
+} {75 400 76 400}
+    
+finish_test