]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Avoid an out-of-bounds read in sqlite3_prepare() and fix a case where the output...
authordanielk1977 <danielk1977@noemail.net>
Thu, 3 Apr 2008 14:36:25 +0000 (14:36 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Thu, 3 Apr 2008 14:36:25 +0000 (14:36 +0000)
FossilOrigin-Name: c287a7b29410be12cf88f886e8e2525a42aa9c03

manifest
manifest.uuid
src/prepare.c
src/sqlite.h.in
src/test1.c
test/capi3.test
test/crash7.test [new file with mode: 0644]
test/vacuum3.test [new file with mode: 0644]

index a9de21cf4187b985a8b2ff33622fd77efc5d14e9..07b2119dd46a0ad51131d8a6d3cb05decdf35054 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Change\sthe\sallocator\sin\smem2.c\s(used\swhen\sSQLITE_MEMDEBUG\sis\sdefined)\sso\sthat\sallocations\sare\snot\srounded\sup\sto\sthe\snearest\s4\sbyte\sboundary.\sFix\sa\scouple\sof\serrors\sin\smalloc.test\srelated\sto\ssqlite3OsAccess()\sreturning\s-1.\s(CVS\s4956)
-D 2008-04-03T10:13:01
+C Avoid\san\sout-of-bounds\sread\sin\ssqlite3_prepare()\sand\sfix\sa\scase\swhere\sthe\soutput\svariable\s*pzTail\swas\sbeing\sset\sincorrectly.\sFix\sfor\s#3027.\s(CVS\s4957)
+D 2008-04-03T14:36:26
 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
 F Makefile.in b861627d91df5ee422c54237aa38296954dc0151
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -132,19 +132,19 @@ F src/pager.c 7b302d90674ea411d0856057af9699fe003318e3
 F src/pager.h b1e2258f03878c14b06a95bfa362e8c5c9638170
 F src/parse.y bc1b1cc6f86a0e0b669abdd88ddbdc7c8b67318d
 F src/pragma.c e659c9e443d11854cff2fd250012365ae0ca81ba
-F src/prepare.c 185fb47f1fb3e45a345d523eb391d673f5eb367c
+F src/prepare.c adc7e1fc08dfbab63cd213d4c0aff8f3fa70d477
 F src/printf.c 05d2b44d7b5b80c8a4a09108ddad9c20e254370d
 F src/random.c 2b2db2de4ab491f5a14d3480466f8f4b5a5db74a
 F src/select.c 53bfb7c4da43b2d20f27b5bf0ceab94d53835080
 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
 F src/shell.c 22297fffa6f00a6c6d44020fa13b1184a1bb372d
-F src/sqlite.h.in b1ac824d9fc163a5d2226ebf5990b09a02a11117
+F src/sqlite.h.in 5364513316e0c36cb02b27c479643b400dbde9c7
 F src/sqlite3ext.h faacd0e6a81aabee0861c6d7883c9172e74ef5b3
 F src/sqliteInt.h cfe0b6c4b1a9b4be22f856ca8058ccd1bf0e41a8
 F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
 F src/table.c 2c48c575dd59b3a6c5c306bc55f51a9402cf429a
 F src/tclsqlite.c 1367762764772a233643524c3585b4711a9adcda
-F src/test1.c 342a2628310fa709074d979e695a28a3bb570834
+F src/test1.c 318bed2bfc24b9f454af09c408ffe4a94d03b9e9
 F src/test2.c f0808cc643528b9620e4059ca9bda8346f526121
 F src/test3.c c715b5a8a6415d7b2c67f97c394eef488b6f7e63
 F src/test4.c c2c0f5dc907f1346f5d4b65eb5799f11eb9e4071
@@ -218,7 +218,7 @@ F test/blob.test f2dbdbf1159674283645c2636436839313ee7131
 F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0
 F test/cache.test 3ff445c445742a7b6b9ba6e1d62a25263f9424b9
 F test/capi2.test cc64df7560a96f848f919ea2926c60acf639684b
-F test/capi3.test 928999c4fb7c70239a4c7b8f9fa52d5cdba9b568
+F test/capi3.test 8113010cd06a94b7ac72524858968069b7cac8e3
 F test/capi3b.test 664eb55318132f292f2c436f90906f578cad6b97
 F test/capi3c.test 976673c1c5caef84201473ea5f7bb7b3093935a8
 F test/cast.test ce8f14fc80f70b30ed984480cc0d8914a459e8f9
@@ -246,6 +246,7 @@ F test/crash3.test 0b09687ae1a3ccbcefdfaeb4b963e26e36255d76
 F test/crash4.test 02ff4f15c149ca1e88a5c299b4896c84d9450c3b
 F test/crash5.test c7ddcf7ca83abc19901b977732144234ac72a938
 F test/crash6.test 873d851c5ba2a46e0f9974c54e1d4a77d9a587d5
+F test/crash7.test e20a7b9ee1d16eaef7c94a4cb7ed2191b4d05970
 F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
 F test/createtab.test 199cf68f44e5d9e87a0b8afc7130fdeb4def3272
 F test/cse.test 4b8a49decaefccb835ecc67249277be491713f6c
@@ -519,6 +520,7 @@ F test/utf16.test 20e2d9ba0d57e952a18b1ac8deab9ad49e082893
 F test/utf16align.test 7360e84472095518c56746f76b1f9d4dce99fb4d
 F test/vacuum.test f67853a15caa120af591f819670f01a11fcc2bfc
 F test/vacuum2.test d3b9691541fe6ed5c711f547a1c7d70e9760ac6f
+F test/vacuum3.test 72fbc903b085cd5f8b3a513b23f8ce44f7e0b06f
 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
 F test/veryquick.test 9bba6886026bb58a7332b6c96fd8270469f02177
 F test/view.test 4864e3841ab3213a95297718b94d5d6a8d3bc78b
@@ -621,7 +623,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P e8529455803e0dab167f4faba5846fa1eafef741
-R ad2bb86bdc9a3800369a1a0fec7f9426
+P fd97f8762cb1e4653c932402940f74d7c0ebf71f
+R 4cbad59c692acf4f8287734f3525dd14
 U danielk1977
-Z 8a37a96ffe96147a3305789b321aea9b
+Z e74a22ea6ae0b08ba9441bfc8876ae6c
index 12c3213bf545e4ac4a2c6f963a194a9221fc5fa7..ba9f5ef27c2e7d8ae3d4739098b5c26a50fe8c8d 100644 (file)
@@ -1 +1 @@
-fd97f8762cb1e4653c932402940f74d7c0ebf71f
\ No newline at end of file
+c287a7b29410be12cf88f886e8e2525a42aa9c03
\ No newline at end of file
index bdb3d37c0283d162c32710d4dde8888cb2dbd374..b52667801b8d9fbaec0beb2b55c22c5f644264a9 100644 (file)
@@ -13,7 +13,7 @@
 ** interface, and routines that contribute to loading the database schema
 ** from disk.
 **
-** $Id: prepare.c,v 1.82 2008/03/25 09:47:35 danielk1977 Exp $
+** $Id: prepare.c,v 1.83 2008/04/03 14:36:26 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -552,7 +552,7 @@ static int sqlite3Prepare(
   
   memset(&sParse, 0, sizeof(sParse));
   sParse.db = db;
-  if( nBytes>=0 && zSql[nBytes]!=0 ){
+  if( nBytes>=0 && zSql[nBytes-1]!=0 ){
     char *zSqlCopy;
     int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
     if( nBytes>mxLen ){
@@ -564,8 +564,10 @@ static int sqlite3Prepare(
     if( zSqlCopy ){
       sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg);
       sqlite3_free(zSqlCopy);
+      sParse.zTail = &zSql[sParse.zTail-zSqlCopy];
+    }else{
+      sParse.zTail = &zSql[nBytes];
     }
-    sParse.zTail = &zSql[nBytes];
   }else{
     sqlite3RunParser(&sParse, zSql, &zErrMsg);
   }
index d6c68ccb2c7e22d270af43fddba1b9328e61b20b..c713988d8d53c93bb539191755b56ea260073dc2 100644 (file)
@@ -30,7 +30,7 @@
 ** the version number) and changes its name to "sqlite3.h" as
 ** part of the build process.
 **
-** @(#) $Id: sqlite.h.in,v 1.301 2008/03/26 18:34:43 danielk1977 Exp $
+** @(#) $Id: sqlite.h.in,v 1.302 2008/04/03 14:36:26 danielk1977 Exp $
 */
 #ifndef _SQLITE3_H_
 #define _SQLITE3_H_
@@ -2292,7 +2292,11 @@ int sqlite3_limit(sqlite3*, int id, int newVal);
 ** If nByte is non-negative, then it is the maximum number of 
 ** bytes read from zSql.  When nByte is non-negative, the
 ** zSql string ends at either the first '\000' or '\u0000' character or 
-** until the nByte-th byte, whichever comes first. {END}
+** until the nByte-th byte, whichever comes first. If the caller knows
+** that the supplied string is nul-terminated, then there is a small
+** performance advantage to be had by passing an nByte parameter that 
+** is equal to the number of bytes in the input string <i>including</i> 
+** the nul-terminator bytes.{END}
 **
 ** *pzTail is made to point to the first byte past the end of the
 ** first SQL statement in zSql.  These routines only compiles the first
index 25846ad24be09b3a7d80af4b96efe41cc5e1421b..5b477a83acbb5b1eeb3bf7831ec8e8b7ea913416 100644 (file)
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test1.c,v 1.295 2008/03/22 01:07:18 drh Exp $
+** $Id: test1.c,v 1.296 2008/04/03 14:36:26 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -3052,6 +3052,9 @@ static int test_prepare(
     if( bytes>=0 ){
       bytes = bytes - (zTail-zSql);
     }
+    if( strlen(zTail)<bytes ){
+      bytes = strlen(zTail);
+    }
     Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0);
   }
   if( rc!=SQLITE_OK ){
index cf3b8bb525edf7aebb7dce6d97c585c0f74a23d3..09a33370def33d68f828e69008cfb9905d5f1418 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this script testing the callback-free C/C++ API.
 #
-# $Id: capi3.test,v 1.61 2008/03/19 13:03:34 drh Exp $
+# $Id: capi3.test,v 1.62 2008/04/03 14:36:26 danielk1977 Exp $
 #
 
 set testdir [file dirname $argv0]
@@ -74,15 +74,28 @@ do_test capi3-1.4 {
   set TAIL
 } {SELECT 10}
 do_test capi3-1.5 {
+  set sql {SELECT name FROM sqlite_master;SELECT 10}
+  set STMT [sqlite3_prepare $DB $sql [string length $sql] TAIL]
+  sqlite3_finalize $STMT
+  set TAIL
+} {SELECT 10}
+do_test capi3-1.6 {
+  set sql {SELECT name FROM sqlite_master;SELECT 10}
+  set STMT [sqlite3_prepare $DB $sql [expr [string length $sql]+1] TAIL]
+  sqlite3_finalize $STMT
+  set TAIL
+} {SELECT 10}
+
+do_test capi3-1.7 {
   set sql {SELECT namex FROM sqlite_master}
   catch {
     set STMT [sqlite3_prepare $DB $sql -1 TAIL]
   }
 } {1}
-do_test capi3-1.6 {
+do_test capi3-1.8 {
   sqlite3_errcode $DB
 } {SQLITE_ERROR}
-do_test capi3-1.7 {
+do_test capi3-1.9 {
   sqlite3_errmsg $DB
 } {no such column: namex}
 
diff --git a/test/crash7.test b/test/crash7.test
new file mode 100644 (file)
index 0000000..fc0596a
--- /dev/null
@@ -0,0 +1,82 @@
+# 2008 March 20
+#
+# 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.
+#
+#***********************************************************************
+#
+# $Id: crash7.test,v 1.1 2008/04/03 14:36:26 danielk1977 Exp $
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+ifcapable !crashtest {
+  finish_test
+  return
+}
+
+proc signature {} {
+  return [db eval {SELECT count(*), md5sum(a), md5sum(b), md5sum(c) FROM abc}]
+}
+
+foreach f [list test.db test.db-journal] {
+  for {set ii 1} {$ii < 64} {incr ii} {
+    db close
+    file delete test.db
+    sqlite3 db test.db
+  
+    set from_size [expr 1024 << ($ii&3)]
+    set to_size   [expr 1024 << (($ii>>2)&3)]
+  
+    execsql "
+      PRAGMA page_size = $from_size;
+      BEGIN;
+      CREATE TABLE abc(a PRIMARY KEY, b, c);
+      INSERT INTO abc VALUES(randomblob(100), randomblob(200), randomblob(1000));
+      INSERT INTO abc 
+          SELECT randomblob(1000), randomblob(200), randomblob(100)
+          FROM abc;
+      INSERT INTO abc 
+          SELECT randomblob(100), randomblob(200), randomblob(1000)
+          FROM abc;
+      INSERT INTO abc 
+          SELECT randomblob(100), randomblob(200), randomblob(1000)
+          FROM abc;
+      INSERT INTO abc 
+          SELECT randomblob(100), randomblob(200), randomblob(1000)
+          FROM abc;
+      INSERT INTO abc 
+          SELECT randomblob(100), randomblob(200), randomblob(1000)
+          FROM abc WHERE [expr $ii&16];
+      INSERT INTO abc 
+          SELECT randomblob(25), randomblob(45), randomblob(9456)
+          FROM abc WHERE [expr $ii&32];
+      INSERT INTO abc 
+          SELECT randomblob(100), randomblob(200), randomblob(1000)
+          FROM abc WHERE [expr $ii&8];
+      INSERT INTO abc 
+          SELECT randomblob(25), randomblob(45), randomblob(9456)
+          FROM abc WHERE [expr $ii&4];
+      COMMIT;
+    "
+  
+    set sig [signature]
+    db close
+  
+    do_test crash7-1.$ii.crash {
+       crashsql -file $f "
+         PRAGMA page_size = $to_size;
+         VACUUM;
+       "
+    } {1 {child process exited abnormally}}
+  
+    sqlite3 db test.db
+    integrity_check crash7-1.$ii.integrity
+  } 
+}
+
+finish_test
diff --git a/test/vacuum3.test b/test/vacuum3.test
new file mode 100644 (file)
index 0000000..342e459
--- /dev/null
@@ -0,0 +1,268 @@
+# 2007 March 19
+#
+# 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 changing the database page size using a 
+# VACUUM statement.
+#
+# $Id: vacuum3.test,v 1.1 2008/04/03 14:36:26 danielk1977 Exp $
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+# If the VACUUM statement is disabled in the current build, skip all
+# the tests in this file.
+#
+ifcapable !vacuum {
+  finish_test
+  return
+}
+
+
+#-------------------------------------------------------------------
+# Test cases vacuum3-1.* convert a simple 2-page database between a 
+# few different page sizes.
+#
+do_test vacuum3-1.1 {
+  execsql {
+    PRAGMA page_size = 1024;
+    CREATE TABLE t1(a, b, c);
+    INSERT INTO t1 VALUES(1, 2, 3);
+  }
+} {}
+do_test vacuum3-1.2 {
+  execsql { PRAGMA page_size }
+} {1024}
+do_test vacuum3-1.3 {
+  file size test.db
+} {2048}
+
+set I 4
+foreach {request actual database} [list \
+  2048 2048 4096                        \
+  1024 1024 2048                        \
+  1170 1024 2048                        \
+  256  1024 2048                        \
+  512  512  1024                        \
+  4096 4096 8192                        \
+  1024 1024 2048                        \
+] {
+if {$I==10} breakpoint
+  do_test vacuum3-1.$I.1 {
+    execsql " 
+      PRAGMA page_size = $request;
+      VACUUM;
+    "
+    execsql { PRAGMA page_size }
+  } $actual
+  do_test vacuum3-1.$I.2 {
+    file size test.db
+  } $database
+  do_test vacuum3-1.$I.3 {
+    execsql { SELECT * FROM t1 }
+  } {1 2 3}
+  integrity_check vacuum3-1.$I.4
+
+  incr I
+}
+
+#-------------------------------------------------------------------
+# Test cases vacuum3-2.* convert a simple 3-page database between a 
+# few different page sizes.
+#
+do_test vacuum3-2.1 {
+  execsql {
+    PRAGMA page_size = 1024;
+    VACUUM;
+    ALTER TABLE t1 ADD COLUMN d;
+    UPDATE t1 SET d = randomblob(1000);
+  }
+  file size test.db
+} {3072}
+do_test vacuum3-2.2 {
+  execsql { PRAGMA page_size }
+} {1024}
+do_test vacuum3-2.3 {
+  set blob [db one {select d from t1}]
+  string length $blob
+} {1000}
+
+set I 4
+foreach {request actual database} [list \
+  2048 2048 4096                        \
+  1024 1024 3072                        \
+  1170 1024 3072                        \
+  256  1024 3072                        \
+  512  512  2048                        \
+  4096 4096 8192                        \
+  1024 1024 3072                        \
+] {
+if {$I==10} breakpoint
+  do_test vacuum3-2.$I.1 {
+    execsql " 
+      PRAGMA page_size = $request;
+      VACUUM;
+    "
+    execsql { PRAGMA page_size }
+  } $actual
+  do_test vacuum3-2.$I.2 {
+    file size test.db
+  } $database
+  do_test vacuum3-2.$I.3 {
+    execsql { SELECT * FROM t1 }
+  } [list 1 2 3 $blob]
+  integrity_check vacuum3-1.$I.4
+
+  incr I
+}
+
+#-------------------------------------------------------------------
+# Test cases vacuum3-3.* converts a database large enough to include
+# the locking page (in a test environment) between few different 
+# page sizes.
+#
+proc signature {} {
+  return [db eval {SELECT count(*), md5sum(a), md5sum(b), md5sum(c) FROM abc}]
+}
+do_test vacuum3-3.1 {
+  execsql "
+    PRAGMA page_size = 1024;
+    BEGIN;
+    CREATE TABLE abc(a PRIMARY KEY, b, c);
+    INSERT INTO abc VALUES(randomblob(100), randomblob(200), randomblob(1000));
+    INSERT INTO abc 
+        SELECT randomblob(1000), randomblob(200), randomblob(100)
+        FROM abc;
+    INSERT INTO abc 
+        SELECT randomblob(100), randomblob(200), randomblob(1000)
+        FROM abc;
+    INSERT INTO abc 
+        SELECT randomblob(100), randomblob(200), randomblob(1000)
+        FROM abc;
+    INSERT INTO abc 
+        SELECT randomblob(100), randomblob(200), randomblob(1000)
+        FROM abc;
+    INSERT INTO abc 
+        SELECT randomblob(100), randomblob(200), randomblob(1000)
+        FROM abc;
+    INSERT INTO abc 
+        SELECT randomblob(25), randomblob(45), randomblob(9456)
+        FROM abc;
+    INSERT INTO abc 
+        SELECT randomblob(100), randomblob(200), randomblob(1000)
+        FROM abc;
+    INSERT INTO abc 
+        SELECT randomblob(25), randomblob(45), randomblob(9456)
+        FROM abc;
+    COMMIT;
+  "
+} {}
+do_test vacuum3-3.2 {
+  execsql { PRAGMA page_size }
+} {1024}
+
+set ::sig [signature]
+
+set I 3
+foreach {request actual} [list \
+  2048 2048                    \
+  1024 1024                    \
+  1170 1024                    \
+  256  1024                    \
+  512  512                     \
+  4096 4096                    \
+  1024 1024                    \
+] {
+if {$I==10} breakpoint
+  do_test vacuum3-3.$I.1 {
+    execsql " 
+      PRAGMA page_size = $request;
+      VACUUM;
+    "
+    execsql { PRAGMA page_size }
+  } $actual
+  do_test vacuum3-3.$I.2 {
+    signature
+  } $::sig
+  integrity_check vacuum3-3.$I.3
+
+  incr I
+}
+
+do_ioerr_test vacuum3-ioerr-1 -cksum true -sqlprep { 
+  PRAGMA page_size = 1024;
+  BEGIN; 
+  CREATE TABLE t1(a, b, c); 
+  INSERT INTO t1 VALUES(1, randstr(50,50), randstr(50,50)); 
+  INSERT INTO t1 SELECT a+2, b||'-'||rowid, c||'-'||rowid FROM t1; 
+  INSERT INTO t1 SELECT a+4, b||'-'||rowid, c||'-'||rowid FROM t1;
+  INSERT INTO t1 SELECT a+8, b||'-'||rowid, c||'-'||rowid FROM t1;
+  INSERT INTO t1 SELECT a+16, b||'-'||rowid, c||'-'||rowid FROM t1;
+  INSERT INTO t1 SELECT a+32, b||'-'||rowid, c||'-'||rowid FROM t1;
+  INSERT INTO t1 SELECT a+64, b||'-'||rowid, c||'-'||rowid FROM t1;
+  INSERT INTO t1 SELECT a+128, b||'-'||rowid, c||'-'||rowid FROM t1;
+  INSERT INTO t1 VALUES(1, randstr(600,600), randstr(600,600));
+  CREATE TABLE t2 AS SELECT * FROM t1;
+  CREATE TABLE t3 AS SELECT * FROM t1;
+  COMMIT;
+  DROP TABLE t2;
+} -sqlbody {
+  PRAGMA page_size = 4096;
+  VACUUM;
+} 
+do_ioerr_test vacuum3-ioerr-2 -cksum true -sqlprep { 
+  PRAGMA page_size = 2048;
+  BEGIN; 
+  CREATE TABLE t1(a, b, c); 
+  INSERT INTO t1 VALUES(1, randstr(50,50), randstr(50,50)); 
+  INSERT INTO t1 SELECT a+2, b||'-'||rowid, c||'-'||rowid FROM t1; 
+  INSERT INTO t1 SELECT a+4, b||'-'||rowid, c||'-'||rowid FROM t1;
+  INSERT INTO t1 SELECT a+8, b||'-'||rowid, c||'-'||rowid FROM t1;
+  INSERT INTO t1 SELECT a+16, b||'-'||rowid, c||'-'||rowid FROM t1;
+  INSERT INTO t1 SELECT a+32, b||'-'||rowid, c||'-'||rowid FROM t1;
+  INSERT INTO t1 SELECT a+64, b||'-'||rowid, c||'-'||rowid FROM t1;
+  INSERT INTO t1 SELECT a+128, b||'-'||rowid, c||'-'||rowid FROM t1;
+  INSERT INTO t1 VALUES(1, randstr(600,600), randstr(600,600));
+  CREATE TABLE t2 AS SELECT * FROM t1;
+  CREATE TABLE t3 AS SELECT * FROM t1;
+  COMMIT;
+  DROP TABLE t2;
+} -sqlbody {
+  PRAGMA page_size = 512;
+  VACUUM;
+} 
+
+source $testdir/malloc_common.tcl
+if {$MEMDEBUG} {
+  do_malloc_test vacuum3-malloc-1 -sqlprep { 
+    PRAGMA page_size = 2048;
+    BEGIN; 
+    CREATE TABLE t1(a, b, c); 
+    INSERT INTO t1 VALUES(1, randstr(50,50), randstr(50,50)); 
+    INSERT INTO t1 SELECT a+2, b||'-'||rowid, c||'-'||rowid FROM t1; 
+    INSERT INTO t1 SELECT a+4, b||'-'||rowid, c||'-'||rowid FROM t1;
+    INSERT INTO t1 SELECT a+8, b||'-'||rowid, c||'-'||rowid FROM t1;
+    INSERT INTO t1 SELECT a+16, b||'-'||rowid, c||'-'||rowid FROM t1;
+    INSERT INTO t1 SELECT a+32, b||'-'||rowid, c||'-'||rowid FROM t1;
+    INSERT INTO t1 SELECT a+64, b||'-'||rowid, c||'-'||rowid FROM t1;
+    INSERT INTO t1 SELECT a+128, b||'-'||rowid, c||'-'||rowid FROM t1;
+    INSERT INTO t1 VALUES(1, randstr(600,600), randstr(600,600));
+    CREATE TABLE t2 AS SELECT * FROM t1;
+    CREATE TABLE t3 AS SELECT * FROM t1;
+    COMMIT;
+    DROP TABLE t2;
+  } -sqlbody {
+    PRAGMA page_size = 512;
+    VACUUM;
+  } 
+}
+
+finish_test
+