]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a case where database corruption was causing an invalid reference. (CVS 5484)
authordanielk1977 <danielk1977@noemail.net>
Sat, 26 Jul 2008 18:26:10 +0000 (18:26 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Sat, 26 Jul 2008 18:26:10 +0000 (18:26 +0000)
FossilOrigin-Name: 7aecabacf924ad8c1f9f4e707d0c56e433e3a434

manifest
manifest.uuid
src/vdbe.c
src/vdbeInt.h
src/vdbeaux.c
test/corrupt7.test

index f70618036508fa125b9b155086732621b055948d..f0aa60eeb7ecc11e99d71390a4a5fc2c652017d9 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\san\sSQLITE_OMIT_LOCALTIME\saround\sthe\s"utc"\smodifier\sin\sdate/time\sfunctions.\s(CVS\s5483)
-D 2008-07-25T16:39:25
+C Fix\sa\scase\swhere\sdatabase\scorruption\swas\scausing\san\sinvalid\sreference.\s(CVS\s5484)
+D 2008-07-26T18:26:10
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in d677b8dbc24fd815043e87e9350f8d296ab40f0d
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -183,11 +183,11 @@ F src/update.c 4e698fcc0c91c241a960304c4236dc3a49603155
 F src/utf.c 8d52f620a7153d90b058502124fe51d821fcdf57
 F src/util.c 06c5476b440f141987e5d829efd25900df72f629
 F src/vacuum.c ef342828002debc97514617af3424aea8ef8522c
-F src/vdbe.c cc4c19b88d63fa963a4b9260bcae04b82fb59fbb
+F src/vdbe.c acc17bc1e3463e05dbcb63f93bc0bfc40e31c22f
 F src/vdbe.h c46155c221418bea29ee3a749d5950fcf85a70e2
-F src/vdbeInt.h 30535c1d30ba1b5fb58d8f0e1d1261af976558aa
+F src/vdbeInt.h 3c12ae0982c03ddac43a2531d41e6eca9fd89eb2
 F src/vdbeapi.c 17fa6f432197d759b15d3b37a7d672a34043c078
-F src/vdbeaux.c 05330c212c77dfd43300bc31bfa0044e4f7ec956
+F src/vdbeaux.c 0d221c85240eddbce498cc0136a5edd43927d67e
 F src/vdbeblob.c a20fe9345062b1a1b4cc187dc5fad45c9414033b
 F src/vdbefifo.c c46dae1194e4277bf007144d7e5b0c0b1c24f136
 F src/vdbemem.c 0c72b58ffd759676ce4829f42bacb83842a58c21
@@ -250,7 +250,7 @@ F test/corrupt3.test 263e8bb04e2728df832fddf6973cf54c91db0c32
 F test/corrupt4.test acdb01afaedf529004b70e55de1a6f5a05ae7fff
 F test/corrupt5.test 7796d5bdfe155ed824cee9dff371f49da237cfe0
 F test/corrupt6.test e69b877d478224deab7b66844566258cecacd25e
-F test/corrupt7.test d9a20cf5f65ff39ffc47c4044b6928c2d20d5fda
+F test/corrupt7.test 34d3217f2e1b783e68374430e4049a3416e1d9e9
 F test/corrupt8.test 9992ef7f67cefc576b92373f6bf5ab8775280f51
 F test/corrupt9.test 794d284109c65c8f10a2b275479045e02d163bae
 F test/corruptA.test 99e95620b980161cb3e79f06a884a4bb8ae265ff
@@ -612,7 +612,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P 4528f7b1cce2d009f1bf32bfb8eeaf3ce5531f41
-R 32d546c36bb4bd1763e233152065a44c
-U drh
-Z a513bec2d2da8332fa1d53012814cd44
+P 71486e93b274b7ca954314dd3e4146192a8b6d79
+R 4d93eb3dfa13692d859e807a2f9f466b
+U danielk1977
+Z 7d9fcc3d41d5284180c5db5ee18f0596
index 7d81d6d22c7de1902d4995910408019e0722af6c..67f0e9b2eb9efde93147a51fd22656fd541d2628 100644 (file)
@@ -1 +1 @@
-71486e93b274b7ca954314dd3e4146192a8b6d79
\ No newline at end of file
+7aecabacf924ad8c1f9f4e707d0c56e433e3a434
\ No newline at end of file
index 7a875634e9d53eb658195cb431a971d95c92a7eb..fdf380ca4440644ac193034a98a4e9fc95c14e93 100644 (file)
@@ -43,7 +43,7 @@
 ** in this file for details.  If in doubt, do not deviate from existing
 ** commenting and indentation practices when changing or adding code.
 **
-** $Id: vdbe.c,v 1.763 2008/07/23 21:07:25 drh Exp $
+** $Id: vdbe.c,v 1.764 2008/07/26 18:26:10 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -3136,7 +3136,10 @@ case OP_IsUnique: {        /* jump, in3 */
     zKey = pK->z;
     nKey = pK->n;
 
-    szRowid = sqlite3VdbeIdxRowidLen((u8*)zKey);
+    rc = sqlite3VdbeIdxRowidLen((u8*)zKey, nKey, &szRowid);
+    if( rc!=SQLITE_OK ){
+      goto abort_due_to_error;
+    }
     len = nKey-szRowid;
 
     /* Search for an entry in P1 where all but the last four bytes match K.
index 2100e38309c030838012c3f4a44864efdaa89e8c..50c34d1b9de5eb3a4b0788535ecc2f42b8cc4034 100644 (file)
@@ -15,7 +15,7 @@
 ** 6000 lines long) it was split up into several smaller files and
 ** this header information was factored out.
 **
-** $Id: vdbeInt.h,v 1.149 2008/06/25 00:12:41 drh Exp $
+** $Id: vdbeInt.h,v 1.150 2008/07/26 18:26:10 danielk1977 Exp $
 */
 #ifndef _VDBEINT_H_
 #define _VDBEINT_H_
@@ -390,7 +390,7 @@ int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
 int sqlite3VdbeIdxKeyCompare(Cursor*,UnpackedRecord *,int,const unsigned char*,int*);
 int sqlite3VdbeIdxRowid(BtCursor *, i64 *);
 int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
-int sqlite3VdbeIdxRowidLen(const u8*);
+int sqlite3VdbeIdxRowidLen(const u8*, int, int*);
 int sqlite3VdbeExec(Vdbe*);
 int sqlite3VdbeList(Vdbe*);
 int sqlite3VdbeHalt(Vdbe*);
index dfdaeecc0d33265ca21789937da15b294b6e01cf..9082757030077518a000a9f9f2d16bccc0eb6af1 100644 (file)
@@ -14,7 +14,7 @@
 ** to version 2.8.7, all this code was combined into the vdbe.c source file.
 ** But that file was getting too big so this subroutines were split out.
 **
-** $Id: vdbeaux.c,v 1.399 2008/07/22 05:18:01 shane Exp $
+** $Id: vdbeaux.c,v 1.400 2008/07/26 18:26:10 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -2354,13 +2354,17 @@ int sqlite3VdbeRecordCompare(
 ** an integer rowid).  This routine returns the number of bytes in
 ** that integer.
 */
-int sqlite3VdbeIdxRowidLen(const u8 *aKey){
+int sqlite3VdbeIdxRowidLen(const u8 *aKey, int nKey, int *pRowidLen){
   u32 szHdr;        /* Size of the header */
   u32 typeRowid;    /* Serial type of the rowid */
 
   (void)getVarint32(aKey, szHdr);
+  if( szHdr>nKey ){
+    return SQLITE_CORRUPT_BKPT;
+  }
   (void)getVarint32(&aKey[szHdr-1], typeRowid);
-  return sqlite3VdbeSerialTypeLen(typeRowid);
+  *pRowidLen = sqlite3VdbeSerialTypeLen(typeRowid);
+  return SQLITE_OK;
 }
   
 
@@ -2429,11 +2433,11 @@ int sqlite3VdbeIdxKeyCompare(
   m.db = 0;
   m.flags = 0;
   m.zMalloc = 0;
-  rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m);
-  if( rc ){
+  if( (rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m))
+   || (rc = sqlite3VdbeIdxRowidLen((u8*)m.z, m.n, &lenRowid))
+  ){
     return rc;
   }
-  lenRowid = sqlite3VdbeIdxRowidLen((u8*)m.z);
   if( !pUnpacked ){
     pRec = sqlite3VdbeRecordUnpack(pC->pKeyInfo, nKey, pKey,
                                 zSpace, sizeof(zSpace));
index 3b83eafbc834c4558155f775dea9c50a6cbf0f59..8b0b2fb82d2e5dedc93ce6532594923018f77666 100644 (file)
@@ -14,7 +14,7 @@
 # segfault if it sees a corrupt database file.  It specifically focuses
 # on corrupt cell offsets in a btree page.
 #
-# $Id: corrupt7.test,v 1.3 2008/07/25 14:53:17 drh Exp $
+# $Id: corrupt7.test,v 1.4 2008/07/26 18:26:10 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -72,4 +72,31 @@ do_test corrupt7-2.2 {
 } {{*** in database main ***
 Corruption detected in cell 15 on page 2}}
 
+do_test corrupt7-3.1 {
+  execsql {
+    DROP TABLE t1;
+    CREATE TABLE t1(a, b);
+    INSERT INTO t1 VALUES(1, 'one');
+    INSERT INTO t1 VALUES(100, 'one hundred');
+    INSERT INTO t1 VALUES(100000, 'one hundred thousand');
+    CREATE INDEX i1 ON t1(b);
+  }
+  db close
+
+  # Locate the 3rd cell in the index.
+  set cell_offset [hexio_get_int [hexio_read test.db [expr 1024*2 + 12] 2]]
+  incr cell_offset [expr 1024*2]
+  incr cell_offset 1
+
+  # This write corrupts the "header-size" field of the database record
+  # stored in the index cell. At one point this was causing sqlite to 
+  # reference invalid memory.
+  hexio_write test.db $cell_offset FFFF7F
+  
+  sqlite3 db test.db
+  catchsql {
+    SELECT b FROM t1 WHERE b > 'o' AND b < 'p';
+  }
+} {1 {database disk image is malformed}}
+
 finish_test