]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Verify that the sqlite_sequence table exists and is in approximately the
authordrh <drh@noemail.net>
Wed, 23 May 2018 16:50:21 +0000 (16:50 +0000)
committerdrh <drh@noemail.net>
Wed, 23 May 2018 16:50:21 +0000 (16:50 +0000)
correct format prior to using it to process an autoincrement table.
Fix for ticket [d8dc2b3a58cd5dc2918a1d4a].

FossilOrigin-Name: e199e859ace4f8381c6380175206e7a276e3f2228fadbbca9341bca8d2fc445d

manifest
manifest.uuid
src/insert.c
src/sqlite.h.in
test/autoinc.test

index a4a4960c57daaa6fe9198aefb32bf6c75c43221c..aaa97903f97d906d70a6de88196a7dc5ddf888ec 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\ssupport\sfor\sauxiliary\scolumns\sto\sthe\srtree\sextension.
-D 2018-05-18T17:58:33.081
+C Verify\sthat\sthe\ssqlite_sequence\stable\sexists\sand\sis\sin\sapproximately\sthe\ncorrect\sformat\sprior\sto\susing\sit\sto\sprocess\san\sautoincrement\stable.\nFix\sfor\sticket\s[d8dc2b3a58cd5dc2918a1d4a].
+D 2018-05-23T16:50:21.007
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da
@@ -455,7 +455,7 @@ F src/hash.c a12580e143f10301ed5166ea4964ae2853d3905a511d4e0c44497245c7ce1f7a
 F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
-F src/insert.c 33a2c72b6182e8ddf697d604cc087c77ff5fc512a32b8b624641d41b390e249e
+F src/insert.c 25f2e3cb93821944dec28921c4cfb7729b3ac6e75d860fd7cd934265404a35b0
 F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e
 F src/loadext.c 6aae5739198d96c51ae6eb97c4a5b1744c22ed7a5a565a5399a717780d48a36b
 F src/main.c b56b2d62d5d11e3f5100b25fca34c13c62a0fe73941f6873454a7fa8a454170d
@@ -496,7 +496,7 @@ F src/resolve.c 6415381a0e9d22c0e7cba33ca4a53f81474190862f5d4838190f5eb5b0b47bc9
 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
 F src/select.c a35d462ee7a3c0856ad7a9d9c8921fbf3d91d911a8f39ad9d61302eb43b24a71
 F src/shell.c.in 51c100206f4b7f86cd9affd80b764825e0edc36ca0190c442e4ca7994611bfe2
-F src/sqlite.h.in 34be2d0d18bf4726538793bdc9854cd87f689fda4b3789515134cdbd68188cf4
+F src/sqlite.h.in 7b3e0f3a5f86eb8c43cf4924171de993210a207f2c51ca59b03f86a0d33c59d5
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 9887b27e69c01e79c2cbe74ef73bf01af5b5703d6a7f0a4371e386d7249cb1c7
 F src/sqliteInt.h 5abdade4744cf3bd567afb65bb144bb3c61f6132f86813b995a5ca79c7b584e8
@@ -626,7 +626,7 @@ F test/auth.test 3d6cd8f3978ba55b1202574e6ecd79c6e00914ca44b9bfd6c1fe6fb873fcac8
 F test/auth2.test 9eb7fce9f34bf1f50d3f366fb3e606be5a2000a1
 F test/auth3.test db21405b95257c24d29273b6b31d0efc59e1d337e3d5804ba2d1fd4897b1ae49
 F test/autoanalyze1.test b9cc3f32a990fa56669b668d237c6d53e983554ae80c0604992e18869a0b2dec
-F test/autoinc.test 83aad64411583aac9ff0b629159ab4662029ab4e3f47090fce4efd132b304484
+F test/autoinc.test c6df81f1de9a5499f912c58e5389d0bcb8d42459df832b65aee24338ad422a42
 F test/autoindex1.test a09958fa756129af10b6582bcbf3cbdf11e305e027b393f393caef801159dee0
 F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df
 F test/autoindex3.test 2dd997d6590438b53e4f715f9278aa91c9299cf3f81246a0915269c35beb790e
@@ -1729,8 +1729,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 e3b2e0a078b82ac6cd3c3312e8ac0983c1375e1052f1e324476d2f8d1b227c30 a350040a3bb962823f92908fb31cade52baf13eab90ef608ca3a8349e4c28c9d
-R c67fcd3e8c429daa0c0bf5aeb356dbf0
-T +closed a350040a3bb962823f92908fb31cade52baf13eab90ef608ca3a8349e4c28c9d
+P c6071ac99cfa4b6272ac4d739fc61a85acb544f6c1c2ae67b31e92aadcc995bd
+R 58a75d6f197e6b4ac0aaca4c0364c2b3
 U drh
-Z 6ceb3a28c710c648a7e5cb8343e1c6ba
+Z c05e2c3d89e368267a2a8ee44da7d50d
index 9a25a0b8693f686b9e916f79f268a3f5d48de4be..1d775eab81900d6065b551bd39cdf7f6e95fd0f5 100644 (file)
@@ -1 +1 @@
-c6071ac99cfa4b6272ac4d739fc61a85acb544f6c1c2ae67b31e92aadcc995bd
\ No newline at end of file
+e199e859ace4f8381c6380175206e7a276e3f2228fadbbca9341bca8d2fc445d
\ No newline at end of file
index d2ac028d91dde57a632c27edc5c1f4b40d4fd666..76293c6018cabdeba7650c0507ddec481445ad7c 100644 (file)
@@ -226,11 +226,26 @@ static int autoIncBegin(
   Table *pTab         /* The table we are writing to */
 ){
   int memId = 0;      /* Register holding maximum rowid */
+  assert( pParse->db->aDb[iDb].pSchema!=0 );
   if( (pTab->tabFlags & TF_Autoincrement)!=0
    && (pParse->db->mDbFlags & DBFLAG_Vacuum)==0
   ){
     Parse *pToplevel = sqlite3ParseToplevel(pParse);
     AutoincInfo *pInfo;
+    Table *pSeqTab = pParse->db->aDb[iDb].pSchema->pSeqTab;
+
+    /* Verify that the sqlite_sequence table exists and is an ordinary
+    ** rowid table with exactly two columns.
+    ** Ticket d8dc2b3a58cd5dc2918a1d4acb 2018-05-23 */
+    if( pSeqTab==0
+     || !HasRowid(pSeqTab)
+     || IsVirtual(pSeqTab)
+     || pSeqTab->nCol!=2
+    ){
+      pParse->nErr++;
+      pParse->rc = SQLITE_CORRUPT_SEQUENCE;
+      return 0;
+    }
 
     pInfo = pToplevel->pAinc;
     while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; }
index 0cd06d09f0b7a5125e9b5b7284f425aa132ac4e8..fe0f14e2923ac6c2d32a0269c5f21f3c3dba7c67 100644 (file)
@@ -511,6 +511,7 @@ int sqlite3_exec(
 #define SQLITE_CANTOPEN_FULLPATH       (SQLITE_CANTOPEN | (3<<8))
 #define SQLITE_CANTOPEN_CONVPATH       (SQLITE_CANTOPEN | (4<<8))
 #define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
+#define SQLITE_CORRUPT_SEQUENCE        (SQLITE_CORRUPT | (2<<8))
 #define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
 #define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))
 #define SQLITE_READONLY_ROLLBACK       (SQLITE_READONLY | (3<<8))
index 196743576b9fd8548f7bcfaa33007358ed9384bc..0ce09b223c29f187cccc8fb1a87dd20dbb941622 100644 (file)
@@ -684,4 +684,159 @@ do_execsql_test autoinc-11.1 {
   SELECT seq FROM sqlite_sequence WHERE name='t11';
 } {5}
 
+# 2018-05-23 ticket d8dc2b3a58cd5dc2918a1d4acbba4676a23ada4c
+# Does not crash if the sqlite_sequence table schema is missing
+# or corrupt.
+#
+do_test autoinc-12.1 {
+  db close
+  forcedelete test.db
+  sqlite3 db test.db
+  db eval {
+    CREATE TABLE fake_sequence(name TEXT PRIMARY KEY,seq) WITHOUT ROWID;
+    PRAGMA writable_schema=on;
+    UPDATE sqlite_master SET
+     sql=replace(sql,'fake_','sqlite_'),
+     name='sqlite_sequence',
+     tbl_name='sqlite_sequence'
+     WHERE name='fake_sequence';
+  }
+  db close
+  sqlite3 db test.db
+  set res [catch {db eval {
+    CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);
+    INSERT INTO t1(b) VALUES('one');
+  }} msg]
+  lappend res $msg
+} {1 {database disk image is malformed}}
+do_test autoinc-12.2 {
+  db close
+  forcedelete test.db
+  sqlite3 db test.db
+  db eval {
+   CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);
+   INSERT INTO t1(b) VALUES('one');
+   PRAGMA writable_schema=on;
+   UPDATE sqlite_master SET
+     sql=replace(sql,'sqlite_','x_'),
+     name='x_sequence',
+     tbl_name='x_sequence'
+    WHERE name='sqlite_sequence';
+  }
+  db close
+  sqlite3 db test.db
+  set res [catch {db eval {
+    INSERT INTO t1(b) VALUES('two');
+  }} msg]
+  lappend res $msg
+} {1 {database disk image is malformed}}
+do_test autoinc-12.3 {
+  db close
+  forcedelete test.db
+  sqlite3 db test.db
+  db eval {
+   CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);
+   INSERT INTO t1(b) VALUES('one');
+   PRAGMA writable_schema=on;
+   UPDATE sqlite_master SET
+     sql='CREATE VIRTUAL TABLE sqlite_sequence USING sqlite_dbpage'
+    WHERE name='sqlite_sequence';
+  }
+  db close
+  sqlite3 db test.db
+  set res [catch {db eval {
+    INSERT INTO t1(b) VALUES('two');
+  }} msg]
+  lappend res $msg
+} {1 {database disk image is malformed}}
+do_test autoinc-12.4 {
+  db close
+  forcedelete test.db
+  sqlite3 db test.db
+  db eval {
+    CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);
+    INSERT INTO t1(b) VALUES('one');
+    CREATE TABLE fake(name TEXT PRIMARY KEY,seq) WITHOUT ROWID;
+  }
+  set root1 [db one {SELECT rootpage FROM sqlite_master
+                     WHERE name='sqlite_sequence'}]
+  set root2 [db one {SELECT rootpage FROM sqlite_master
+                     WHERE name='fake'}]
+  db eval {
+   PRAGMA writable_schema=on;
+   UPDATE sqlite_master SET rootpage=$root2
+    WHERE name='sqlite_sequence';
+   UPDATE sqlite_master SET rootpage=$root1
+    WHERE name='fake';
+  }
+  db close
+  sqlite3 db test.db
+  set res [catch {db eval {
+    INSERT INTO t1(b) VALUES('two');
+  }} msg]
+  lappend res $msg
+} {1 {database disk image is malformed}}
+breakpoint
+do_test autoinc-12.5 {
+  db close
+  forcedelete test.db
+  sqlite3 db test.db
+  db eval {
+    CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);
+    INSERT INTO t1(b) VALUES('one');
+    PRAGMA writable_schema=on;
+    UPDATE sqlite_master SET
+       sql='CREATE TABLE sqlite_sequence(x)'
+      WHERE name='sqlite_sequence';
+  }
+  db close
+  sqlite3 db test.db
+  set res [catch {db eval {
+    INSERT INTO t1(b) VALUES('two');
+  }} msg]
+  lappend res $msg
+} {1 {database disk image is malformed}}
+do_test autoinc-12.6 {
+  db close
+  forcedelete test.db
+  sqlite3 db test.db
+  db eval {
+    CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);
+    INSERT INTO t1(b) VALUES('one');
+    PRAGMA writable_schema=on;
+    UPDATE sqlite_master SET
+       sql='CREATE TABLE sqlite_sequence(x,y INTEGER PRIMARY KEY)'
+      WHERE name='sqlite_sequence';
+  }
+  db close
+  sqlite3 db test.db
+  set res [catch {db eval {
+    INSERT INTO t1(b) VALUES('two'),('three'),('four');
+    INSERT INTO t1(b) VALUES('five');
+    PRAGMA integrity_check;
+  }} msg]
+  lappend res $msg
+} {0 ok}
+do_test autoinc-12.7 {
+  db close
+  forcedelete test.db
+  sqlite3 db test.db
+  db eval {
+    CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);
+    INSERT INTO t1(b) VALUES('one');
+    PRAGMA writable_schema=on;
+    UPDATE sqlite_master SET
+       sql='CREATE TABLE sqlite_sequence(y INTEGER PRIMARY KEY,x)'
+      WHERE name='sqlite_sequence';
+  }
+  db close
+  sqlite3 db test.db
+  set res [catch {db eval {
+    INSERT INTO t1(b) VALUES('two'),('three'),('four');
+    INSERT INTO t1(b) VALUES('five');
+    PRAGMA integrity_check;
+  }} msg]
+  lappend res $msg
+} {0 ok}
+
 finish_test