]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Avoid ever writing before the start of an allocated buffer in the DIRECT_OVERFLOW_REA...
authordan <dan@noemail.net>
Wed, 1 Oct 2014 12:01:10 +0000 (12:01 +0000)
committerdan <dan@noemail.net>
Wed, 1 Oct 2014 12:01:10 +0000 (12:01 +0000)
FossilOrigin-Name: c3c15d20c6913811956a5041c959a56ca4eeb5eb

manifest
manifest.uuid
src/btree.c
test/ovfl.test [new file with mode: 0644]

index 4f1b85c92d750a7c7eeec7746d4f79c4d81caf21..22b9dc1ea8e2648ee6abe6de1e33dc3b10253f0f 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Improvements\sto\sthe\snew\ssyntax-tree\soutput\sroutines:\s\sOmit\sthe\s"END\sSELECT"\nmark\sand\sinstead\sterminate\sthe\sgraph\sat\sthe\slast\sitem.\s\sIncrease\sthe\smaximum\ntree\sdepth\sto\s100.
-D 2014-09-30T19:04:41.396
+C Avoid\sever\swriting\sbefore\sthe\sstart\sof\san\sallocated\sbuffer\sin\sthe\sDIRECT_OVERFLOW_READ\scode.\sFix\sfor\s[e3a290961a6].
+D 2014-10-01T12:01:10.959
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -172,7 +172,7 @@ F src/auth.c d8abcde53426275dab6243b441256fcd8ccbebb2
 F src/backup.c a31809c65623cc41849b94d368917f8bb66e6a7e
 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
 F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5
-F src/btree.c ede8348a7d623257ee6c06ca4796ceaee13b8657
+F src/btree.c fa00618117fb6bb46c243452c56997c0d22d4fc9
 F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8
 F src/btreeInt.h 1bd7957161a1346a914f1f09231610e777a8e58d
 F src/build.c bde83dd5cf812e310a7e5ad2846790a14745bef4
@@ -749,6 +749,7 @@ F test/orderby5.test 8f08a54836d21fb7c70245360751aedd1c2286fb
 F test/orderby6.test 8b38138ab0972588240b3fca0985d2e400432859
 F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da
 F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3
+F test/ovfl.test 4f7ca651cba5c059a12d8c67dddd49bec5747799
 F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa
 F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
@@ -1200,7 +1201,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 b6b289182f6590288ebc7b9efbcb29b6b4480538
-R cfd4c6e5c7836f29218c39baf2122e42
-U drh
-Z 3bfcd52f8fd5ecba827fd0c1ccf2615c
+P 5ce05757aac80b99c3b2141cd301809f8e28e661
+R 8b86b2d12e4b9100e4b861428290f6cc
+U dan
+Z 9b09f2a5bed05af5296fa69f0721cad2
index f78de65f58082a597456d83d241a2e2de460b14e..8b1c98cc6ba63c3dff641dbaf9744f908e290cb1 100644 (file)
@@ -1 +1 @@
-5ce05757aac80b99c3b2141cd301809f8e28e661
\ No newline at end of file
+c3c15d20c6913811956a5041c959a56ca4eeb5eb
\ No newline at end of file
index 503a2fb5d0462964e03e932ea620bff8f639af41..12dcb44cba51ff5ba3c85f06cf8c831e9a601362 100644 (file)
@@ -4022,6 +4022,7 @@ static int accessPayload(
   MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */
   BtShared *pBt = pCur->pBt;                  /* Btree this cursor belongs to */
 #ifdef SQLITE_DIRECT_OVERFLOW_READ
+  unsigned char * const pBufStart = pBuf;
   int bEnd;                                 /* True if reading to end of data */
 #endif
 
@@ -4149,6 +4150,7 @@ static int accessPayload(
         **   4) there is no open write-transaction, and
         **   5) the database is not a WAL database,
         **   6) all data from the page is being read.
+        **   7) at least 4 bytes have already been read into the output buffer 
         **
         ** then data can be read directly from the database file into the
         ** output buffer, bypassing the page-cache altogether. This speeds
@@ -4160,9 +4162,11 @@ static int accessPayload(
          && pBt->inTransaction==TRANS_READ                     /* (4) */
          && (fd = sqlite3PagerFile(pBt->pPager))->pMethods     /* (3) */
          && pBt->pPage1->aData[19]==0x01                       /* (5) */
+         && &pBuf[-4]>=pBufStart                               /* (7) */
         ){
           u8 aSave[4];
           u8 *aWrite = &pBuf[-4];
+          assert( aWrite>=pBufStart );                         /* hence (7) */
           memcpy(aSave, aWrite, 4);
           rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1));
           nextPage = get4byte(aWrite);
diff --git a/test/ovfl.test b/test/ovfl.test
new file mode 100644 (file)
index 0000000..075b1e4
--- /dev/null
@@ -0,0 +1,49 @@
+# 2014 October 01
+#
+# 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.  The
+# focus of this file is testing the SQLITE_DIRECT_OVERFLOW_READ logic.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set testprefix ovfl
+
+# Populate table t2:
+#
+#   CREATE TABLE t1(c1 TEXT, c2 TEXT);
+#
+# with 2000 rows. In each row, c2 spans multiple overflow pages. The text
+# value of c1 ranges in size from 1 to 2000 bytes. The idea is to create
+# at least one row where the first byte of c2 is also the first byte of
+# an overflow page. This was at one point exposing an obscure bug in the
+# SQLITE_DIRECT_OVERFLOW_READ logic.
+#
+do_test 1.1 {
+  set c2 [string repeat abcdefghij 200]
+  execsql {
+    PRAGMA cache_size = 10;
+    CREATE TABLE t1(c1 TEXT, c2 TEXT);
+    BEGIN;
+  }
+  for {set i 1} {$i <= 2000} {incr i} {
+    set c1 [string repeat . $i]
+    execsql { INSERT INTO t1 VALUES($c1, $c2) }
+  }
+  execsql COMMIT
+} {}
+
+do_execsql_test 1.2 {
+  SELECT sum(length(c2)) FROM t1;
+} [expr 2000 * 2000]
+
+finish_test
+
+