]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix crash in delete when existing row has null fields. Previous code
authorshess <shess@noemail.net>
Mon, 9 Apr 2007 20:45:40 +0000 (20:45 +0000)
committershess <shess@noemail.net>
Mon, 9 Apr 2007 20:45:40 +0000 (20:45 +0000)
assumed that the row had values in all columns, sigh.  Fixes bug
http://www.sqlite.org/cvstrac/tktview?tn=2289 . (CVS 3833)

FossilOrigin-Name: 81be7290a4db7b74a533aaf95c7389eb4bde6a88

ext/fts1/fts1.c
ext/fts2/fts2.c
manifest
manifest.uuid
test/fts1l.test [new file with mode: 0644]
test/fts2m.test [new file with mode: 0644]

index ddd4529c7eea7d8c4545d7a94a36488346bcb58f..0d931eca1924d2f7c958a64103bd5d29bc266caf 100644 (file)
@@ -1273,13 +1273,14 @@ static void freeStringArray(int nString, const char **pString){
   int i;
 
   for (i=0 ; i < nString ; ++i) {
-    free((void *) pString[i]);
+    if( pString[i]!=NULL ) free((void *) pString[i]);
   }
   free((void *) pString);
 }
 
 /* select * from %_content where rowid = [iRow]
  * The caller must delete the returned array and all strings in it.
+ * null fields will be NULL in the returned array.
  *
  * TODO: Perhaps we should return pointer/length strings here for consistency
  * with other code which uses pointer/length. */
@@ -1303,7 +1304,11 @@ static int content_select(fulltext_vtab *v, sqlite_int64 iRow,
 
   values = (const char **) malloc(v->nColumn * sizeof(const char *));
   for(i=0; i<v->nColumn; ++i){
-    values[i] = string_dup((char*)sqlite3_column_text(s, i));
+    if( sqlite3_column_type(s, i)==SQLITE_NULL ){
+      values[i] = NULL;
+    }else{
+      values[i] = string_dup((char*)sqlite3_column_text(s, i));
+    }
   }
 
   /* We expect only one row.  We must execute another sqlite3_step()
index 2a52737d703f0d3ee02670b0b83ecf35bc36b69c..e734d32f816f94e57d95ad85889876d07e7fd799 100644 (file)
@@ -1924,13 +1924,14 @@ static void freeStringArray(int nString, const char **pString){
   int i;
 
   for (i=0 ; i < nString ; ++i) {
-    free((void *) pString[i]);
+    if( pString[i]!=NULL ) free((void *) pString[i]);
   }
   free((void *) pString);
 }
 
 /* select * from %_content where rowid = [iRow]
  * The caller must delete the returned array and all strings in it.
+ * null fields will be NULL in the returned array.
  *
  * TODO: Perhaps we should return pointer/length strings here for consistency
  * with other code which uses pointer/length. */
@@ -1954,7 +1955,11 @@ static int content_select(fulltext_vtab *v, sqlite_int64 iRow,
 
   values = (const char **) malloc(v->nColumn * sizeof(const char *));
   for(i=0; i<v->nColumn; ++i){
-    values[i] = string_dup((char*)sqlite3_column_text(s, i));
+    if( sqlite3_column_type(s, i)==SQLITE_NULL ){
+      values[i] = NULL;
+    }else{
+      values[i] = string_dup((char*)sqlite3_column_text(s, i));
+    }
   }
 
   /* We expect only one row.  We must execute another sqlite3_step()
index 0e6d6af4a1690d96d45904416fb4e92a0cb333b7..a1bb28e12023d07259ce7e825791df63ceaf14bd 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sstack\sbuffer\soverrun\sproblem\sin\sthe\stest\sharness.\s(CVS\s3832)
-D 2007-04-09T20:30:11
+C Fix\scrash\sin\sdelete\swhen\sexisting\srow\shas\snull\sfields.\s\sPrevious\scode\nassumed\sthat\sthe\srow\shad\svalues\sin\sall\scolumns,\ssigh.\s\sFixes\sbug\nhttp://www.sqlite.org/cvstrac/tktview?tn=2289\s.\s(CVS\s3833)
+D 2007-04-09T20:45:41
 F Makefile.in 8cab54f7c9f5af8f22fd97ddf1ecfd1e1860de62
 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -22,7 +22,7 @@ F ext/README.txt 913a7bd3f4837ab14d7e063304181787658b14e1
 F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e
 F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b
 F ext/fts1/ft_hash.h 1a35e654a235c2c662d3ca0dfc3138ad60b8b7d5
-F ext/fts1/fts1.c 7585d9cb7ad7bcdf162936ab1fd64868f2f55ea5
+F ext/fts1/fts1.c 1ee986c31a7080d509602fa182738c5a8862fbff
 F ext/fts1/fts1.h 6060b8f62c1d925ea8356cb1a6598073eb9159a6
 F ext/fts1/fts1_hash.c 3196cee866edbebb1c0521e21672e6d599965114
 F ext/fts1/fts1_hash.h 957d378355ed29f672cd5add012ce8b088a5e089
@@ -34,7 +34,7 @@ F ext/fts1/fulltext.h 08525a47852d1d62a0be81d3fc3fe2d23b094efd
 F ext/fts1/simple_tokenizer.c 1844d72f7194c3fd3d7e4173053911bf0661b70d
 F ext/fts1/tokenizer.h 0c53421b832366d20d720d21ea3e1f6e66a36ef9
 F ext/fts2/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
-F ext/fts2/fts2.c 8d69d6e4b48b0de4350e10c9c76649c638e35997
+F ext/fts2/fts2.c acfce1c936d50615f21b63b71f6e86730da64a8c
 F ext/fts2/fts2.h bbdab26d34f91974d5b9ade8b7836c140a7c4ce1
 F ext/fts2/fts2_hash.c b3f22116d4ef0bc8f2da6e3fdc435c86d0951a9b
 F ext/fts2/fts2_hash.h e283308156018329f042816eb09334df714e105e
@@ -219,6 +219,7 @@ F test/fts1f.test 2d6cb10d8b7a4e6edc321bbdb3982f1f48774714
 F test/fts1i.test 6bfe08cdfdced063a39a50c8601da65e6274d879
 F test/fts1j.test e4c0ffcd0ba2adce09c6b7b43ffd0749b5fda5c7
 F test/fts1k.test fdf295cb797ba6a2ef81ec41cb98df0ceb2e572c
+F test/fts1l.test 15c119ed2362b2b28d5300c0540a6a43eab66c36
 F test/fts1porter.test d86e9c3e0c7f8ff95add6582b4b585fb4e02b96d
 F test/fts2a.test 103fc178d134c54c44c1938a4331e9e2030792d9
 F test/fts2b.test 964abc0236c849c07ca1ae496bb25c268ae94816
@@ -232,6 +233,7 @@ F test/fts2i.test 1b22451d1f13f7c509baec620dc3a4a754885dd6
 F test/fts2j.test f68d7611f76309bc8b94170f3740d9fbbc061d9b
 F test/fts2k.test 222d0b3bc8667753f18406aaea9906a6098ea016
 F test/fts2l.test 4c53c89ce3919003765ff4fd8d98ecf724d97dd3
+F test/fts2m.test 4b30142ead6f3ed076e880a2a464064c5ad58c51
 F test/func.test 019d706b2458dfdf239c74cc31143446de1ee44a
 F test/hook.test 7e7645fd9a033f79cce8fdff151e32715e7ec50a
 F test/in.test 369cb2aa1eab02296b4ec470732fe8c131260b1d
@@ -455,7 +457,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P ba5f4a55fad183a1698555b256f43f63451f5fc6
-R 5ef4b02d2117db2ca987c4c827be07e2
-U drh
-Z aefa6d34865394c1dd78203eae52ac99
+P cad9faf3ad99b68be4618dff4b3497b15b9e6d9d
+R 66cd54d39dd95145a99973d21d5eff33
+U shess
+Z 50d829f2eb908722f9e9fda676f48500
index 70d4a8b850350a2310392c10277b4e5e8321e774..051d46b047fdce889948472e3e4eb6f224531930 100644 (file)
@@ -1 +1 @@
-cad9faf3ad99b68be4618dff4b3497b15b9e6d9d
\ No newline at end of file
+81be7290a4db7b74a533aaf95c7389eb4bde6a88
\ No newline at end of file
diff --git a/test/fts1l.test b/test/fts1l.test
new file mode 100644 (file)
index 0000000..924be33
--- /dev/null
@@ -0,0 +1,65 @@
+# 2007 April 9
+#
+# The author disclaims copyright to this source code.
+#
+#*************************************************************************
+# This file implements regression tests for SQLite library.  fts1
+# DELETE handling assumed all fields were non-null.  This was not
+# the intention at all.
+#
+# $Id: fts1l.test,v 1.1 2007/04/09 20:45:42 shess Exp $
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+# If SQLITE_ENABLE_FTS1 is defined, omit this file.
+ifcapable !fts1 {
+  finish_test
+  return
+}
+
+db eval {
+  CREATE VIRTUAL TABLE t1 USING fts1(col_a, col_b);
+
+  INSERT INTO t1(rowid, col_a, col_b) VALUES(1, 'testing', 'testing');
+  INSERT INTO t1(rowid, col_a, col_b) VALUES(2, 'only a', null);
+  INSERT INTO t1(rowid, col_a, col_b) VALUES(3, null, 'only b');
+  INSERT INTO t1(rowid, col_a, col_b) VALUES(4, null, null);
+}
+
+do_test fts1m-1.0 {
+  execsql {
+    SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1;
+  }
+} {2 2 4}
+
+do_test fts1m-1.1 {
+  execsql {
+    DELETE FROM t1 WHERE rowid = 1;
+    SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1;
+  }
+} {1 1 3}
+
+do_test fts1m-1.2 {
+  execsql {
+    DELETE FROM t1 WHERE rowid = 2;
+    SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1;
+  }
+} {0 1 2}
+
+do_test fts1m-1.3 {
+  execsql {
+    DELETE FROM t1 WHERE rowid = 3;
+    SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1;
+  }
+} {0 0 1}
+
+do_test fts1m-1.4 {
+  execsql {
+    DELETE FROM t1 WHERE rowid = 4;
+    SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1;
+  }
+} {0 0 0}
+
+finish_test
diff --git a/test/fts2m.test b/test/fts2m.test
new file mode 100644 (file)
index 0000000..6552637
--- /dev/null
@@ -0,0 +1,65 @@
+# 2007 April 9
+#
+# The author disclaims copyright to this source code.
+#
+#*************************************************************************
+# This file implements regression tests for SQLite library.  fts2
+# DELETE handling assumed all fields were non-null.  This was not
+# the intention at all.
+#
+# $Id: fts2m.test,v 1.1 2007/04/09 20:45:42 shess Exp $
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+# If SQLITE_ENABLE_FTS2 is defined, omit this file.
+ifcapable !fts2 {
+  finish_test
+  return
+}
+
+db eval {
+  CREATE VIRTUAL TABLE t1 USING fts2(col_a, col_b);
+
+  INSERT INTO t1(rowid, col_a, col_b) VALUES(1, 'testing', 'testing');
+  INSERT INTO t1(rowid, col_a, col_b) VALUES(2, 'only a', null);
+  INSERT INTO t1(rowid, col_a, col_b) VALUES(3, null, 'only b');
+  INSERT INTO t1(rowid, col_a, col_b) VALUES(4, null, null);
+}
+
+do_test fts2m-1.0 {
+  execsql {
+    SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1;
+  }
+} {2 2 4}
+
+do_test fts2m-1.1 {
+  execsql {
+    DELETE FROM t1 WHERE rowid = 1;
+    SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1;
+  }
+} {1 1 3}
+
+do_test fts2m-1.2 {
+  execsql {
+    DELETE FROM t1 WHERE rowid = 2;
+    SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1;
+  }
+} {0 1 2}
+
+do_test fts2m-1.3 {
+  execsql {
+    DELETE FROM t1 WHERE rowid = 3;
+    SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1;
+  }
+} {0 0 1}
+
+do_test fts2m-1.4 {
+  execsql {
+    DELETE FROM t1 WHERE rowid = 4;
+    SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1;
+  }
+} {0 0 0}
+
+finish_test