]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a segfault in the sessions module that could follow an OOM.
authordan <dan@noemail.net>
Sat, 27 Sep 2014 18:18:32 +0000 (18:18 +0000)
committerdan <dan@noemail.net>
Sat, 27 Sep 2014 18:18:32 +0000 (18:18 +0000)
FossilOrigin-Name: 09985fa6b60a0bf38e23bbccd4d8e1d1cbf66124

ext/session/session9.test
ext/session/sessionA.test
ext/session/sessionfault.test
ext/session/sqlite3session.c
manifest
manifest.uuid

index 3b42c310613a8adadae1db00f3a024a89bf3c765..a9f61c872f5d9f0f571b3d556ab83a1e18e829ee 100644 (file)
@@ -200,6 +200,7 @@ do_test 3.3 {
 do_test 3.3.1 {
   list [catch {sqlite3changeset_apply db $::ccdel1 conflict_handler} msg] $msg
 } {1 SQLITE_CONSTRAINT}
+
 do_test 3.3.2 {
   list [catch {sqlite3changeset_apply db $::ccdel2 conflict_handler} msg] $msg
 } {1 SQLITE_CONSTRAINT}
@@ -251,4 +252,37 @@ do_catchsql_test 4.3.2 {
 do_catchsql_test 4.3.3 { COMMIT } {0 {}}
 do_catchsql_test 4.3.4 { BEGIN ; COMMIT } {0 {}}
 
+#--------------------------------------------------------------------
+# Test that if a DELETE change cannot be applied due to an 
+# SQLITE_CONSTRAINT error thrown by a trigger program, things do not
+# go awry.
+
+drop_all_tables
+reset_db
+do_execsql_test 5.1 {
+  CREATE TABLE x1(x PRIMARY KEY, y);
+  CREATE TABLE x2(x PRIMARY KEY, y);
+  INSERT INTO x2 VALUES(1, 1);
+  INSERT INTO x1 VALUES(1, 1);
+}
+
+set ::cc [changeset_from_sql { DELETE FROM x1; }]
+
+do_execsql_test 5.2 {
+  INSERT INTO x1 VALUES(1, 1);
+  CREATE TRIGGER tr1 AFTER DELETE ON x1 BEGIN
+    INSERT INTO x2 VALUES(old.x, old.y);
+  END;
+} {}
+
+proc conflict_handler {args} { return "ABORT" }
+do_test 5.3 {
+  list [catch {sqlite3changeset_apply db $::cc conflict_handler} msg] $msg
+} {1 SQLITE_ABORT}
+
+do_execsql_test 5.4 {
+  SELECT * FROM X1;
+} {1 1}
+
 finish_test
+
index 1ca0f1370992f6eb3b37f66048763b5ba9b72e9c..8ee20465192a598449923681f334ecfaf8a0d6e6 100644 (file)
@@ -9,8 +9,7 @@
 #
 #***********************************************************************
 #
-# This file tests that the sessions module handles foreign key constraint
-# violations when applying changesets as required.
+# This file tests that filter callbacks work as required.
 #
 
 if {![info exists testdir]} {
@@ -63,6 +62,46 @@ do_test 2.1 {
   } db2
 } {a b e f}
 
+#-------------------------------------------------------------------------
+# Test that filter callbacks passed to sqlite3changeset_apply() are 
+# invoked correctly.
+#
+reset_db
+do_execsql_test 3.1 {
+  CREATE TABLE t1(a PRIMARY KEY, b);
+  CREATE TABLE t2(x PRIMARY KEY, y);
+}
+
+do_test 3.2 {
+  execsql BEGIN
+  set ::cs [changeset_from_sql { 
+    INSERT INTO t1 VALUES(1, 2);
+    INSERT INTO t2 VALUES('x', 'y');
+  }]
+  execsql ROLLBACK
+  set {} {}
+} {}
+
+proc filter {x y} { 
+  return [string equal $x $y] 
+}
+
+do_test 3.3 {
+  sqlite3changeset_apply db $::cs {} [list filter t1]
+  execsql {
+    SELECT * FROM t1;
+    SELECT * FROM t2;
+  }
+} {1 2}
+
+do_test 3.4 {
+  execsql { DELETE FROM t1 }
+  sqlite3changeset_apply db $::cs {} [list filter t2]
+  execsql {
+    SELECT * FROM t1;
+    SELECT * FROM t2;
+  }
+} {x y}
 
 finish_test
 
index c94589e3729ec2c0488fe598d5e6306b294b77f9..39f27bfe6d5622c2538f2391690b1ed866d0ddb6 100644 (file)
@@ -285,6 +285,38 @@ do_faultsim_test 5.2 -faults oom-tra* -body {
   }
 }
 
+catch {db close}
+catch {db2 close}
+forcedelete test.db
+sqlite3 db test.db
+set abc [string repeat abc 256]
+set def [string repeat def 256]
+execsql "
+  CREATE TABLE t2(a PRIMARY KEY, b);
+  INSERT INTO t2 VALUES(1, '$abc');
+"
+set changeset [changeset_from_sql "
+  INSERT INTO t2 VALUES(2, '$def');
+  DELETE FROM t2 WHERE a = 1;
+"]
+db close
+
+do_faultsim_test 5.3 -faults oom-tra* -body {
+  set ::inverse [sqlite3changeset_invert $::changeset]
+  set {} {}
+} -test {
+  faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
+  if {$testrc==0} {
+    set x [list]
+    sqlite3session_foreach c $::inverse { lappend x $c }
+    foreach c "
+        {INSERT t2 0 X. {} {i 1 t $::abc}}
+        {DELETE t2 0 X. {i 2 t $::def} {}}
+    " { lappend y $c }
+    if {$x != $y} { error "changeset no good" }
+  }
+}
+
 #-------------------------------------------------------------------------
 # Test that OOM errors in sqlite3changeset_concat() are handled correctly.
 #
@@ -515,7 +547,41 @@ do_faultsim_test 10 -faults oom-tra* -prep {
   }
 }
 
+#-------------------------------------------------------------------------
+# Test an OOM with an sqlite3changeset_apply() filter callback.
+#
+reset_db
+do_test 11.prep {
+  execsql {
+    CREATE TABLE t1(a PRIMARY KEY, b);
+    CREATE TABLE t2(x PRIMARY KEY, y);
+    BEGIN;
+  }
+
+  set ::cs [changeset_from_sql { 
+    INSERT INTO t1 VALUES(1, 2);
+    INSERT INTO t2 VALUES('x', 'y');
+  }]
+
+  execsql ROLLBACK
+  set {} {}
+} {}
 
+proc filter {x} { return [string equal t1 $x] } 
+faultsim_save_and_close
+
+do_faultsim_test 11 -faults oom-tra* -prep {
+  faultsim_restore_and_reopen
+} -body {
+  sqlite3changeset_apply db $::cs {} filter
+} -test {
+  faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
+  if {$testrc==0} {
+    if {[db eval {SELECT * FROM t1 UNION ALL SELECT * FROM t2}] != "1 2"} {
+      error "data does not look right"
+    }
+  }
+}
 
 
 finish_test
index 7e69be4cc4aacdd5fd7e021439ff01fa977860f1..ed8d8510833ebb4444dd5e4a7b30c98810ef2555 100644 (file)
@@ -3495,6 +3495,10 @@ static int sessionChangesetApply(
       schemaMismatch = (xFilter && (0==xFilter(pCtx, zNew)));
       if( schemaMismatch ){
         zTab = sqlite3_mprintf("%s", zNew);
+        if( zTab==0 ){
+          rc = SQLITE_NOMEM;
+          break;
+        }
         nTab = (int)strlen(zTab);
         sApply.azCol = (const char **)zTab;
       }else{
index 4cb1bee75c411995d5eea11f4ef08dc992230cd8..0d58beec13735518f61edea8758409ea439069d1 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\ssegfault\sin\sthe\sstreaming\sAPI\sfunctions\striggered\sby\sa\svery\slong\stable\sname.
-D 2014-09-27T16:33:09.345
+C Fix\sa\ssegfault\sin\sthe\ssessions\smodule\sthat\scould\sfollow\san\sOOM.
+D 2014-09-27T18:18:32.969
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in dd5f245aa8c741bc65845747203c8ce2f3fb6c83
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -153,12 +153,12 @@ F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84
 F ext/session/session5.test 8fdfaf9dba28a2f1c6b89b06168bdab1fef2d478
 F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26
 F ext/session/session8.test 7d35947ad329b8966f095d34f9617a9eff52dc65
-F ext/session/session9.test 776e46785c29c11cda01f5205d0f1e8f8f9a46bf
-F ext/session/sessionA.test eb05c13e4ef1ca8046a3a6dbf2d5f6f5b04a11d4
+F ext/session/session9.test b6dd1086de8c59b6f129923425487791f51c689c
+F ext/session/sessionA.test 5543846eb9ca045217262f5d8c9376ce812e1ba5
 F ext/session/sessionB.test d4ac901b43d4922a17dff08bbaa2f5354487ce4d
 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5
-F ext/session/sessionfault.test cf9758bfb6ccd5db5f09f170667a8cea1ac8afa7
-F ext/session/sqlite3session.c 228cca8fdb6fd07942be097c516f22e39ec39e3c
+F ext/session/sessionfault.test bef044d0952c0d62c31c8d2400be72c8684545cc
+F ext/session/sqlite3session.c 0691b8d7434edb07166828778540bb418a7a68e3
 F ext/session/sqlite3session.h b57009fb88835cc4684376bd3eae0d6ab364968a
 F ext/session/test_session.c 56a4ddd443b571c8d365b03197c032bdaed1443a
 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220
@@ -1216,7 +1216,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 bfc8bd80f8b225cebc66478448510ce84223ae7d
-R 9ca53892e63f9c31475266a6b3e34d34
+P d2642543eed54da1ac0f757d43dd4d72482eb752
+R 7328e4de54076fa7989cf4f3b00a08d8
 U dan
-Z f7759b84adfee5a6c178fa61db492ce5
+Z 371024a806f6988dfc33105901bfbbae
index 903686ec1f7c5c3bcfd4ea57f9dadd2395b6ef47..d5a74ccbec5b0b7b9f6db1c6c23c5daaef0a8605 100644 (file)
@@ -1 +1 @@
-d2642543eed54da1ac0f757d43dd4d72482eb752
\ No newline at end of file
+09985fa6b60a0bf38e23bbccd4d8e1d1cbf66124
\ No newline at end of file