| OLD | NEW | 
 | (Empty) | 
|    1 # 2001 September 15 |  | 
|    2 # |  | 
|    3 # The author disclaims copyright to this source code.  In place of |  | 
|    4 # a legal notice, here is a blessing: |  | 
|    5 # |  | 
|    6 #    May you do good and not evil. |  | 
|    7 #    May you find forgiveness for yourself and forgive others. |  | 
|    8 #    May you share freely, never taking more than you give. |  | 
|    9 # |  | 
|   10 #*********************************************************************** |  | 
|   11 # |  | 
|   12 # This file attempts to check the behavior of the SQLite library in  |  | 
|   13 # an out-of-memory situation. When compiled with -DSQLITE_DEBUG=1,  |  | 
|   14 # the SQLite library accepts a special command (sqlite3_memdebug_fail N C) |  | 
|   15 # which causes the N-th malloc to fail.  This special feature is used |  | 
|   16 # to see what happens in the library if a malloc were to really fail |  | 
|   17 # due to an out-of-memory situation. |  | 
|   18 # |  | 
|   19 # $Id: malloc.test,v 1.81 2009/06/24 13:13:45 drh Exp $ |  | 
|   20  |  | 
|   21 set testdir [file dirname $argv0] |  | 
|   22 source $testdir/tester.tcl |  | 
|   23  |  | 
|   24  |  | 
|   25 # Only run these tests if memory debugging is turned on. |  | 
|   26 # |  | 
|   27 source $testdir/malloc_common.tcl |  | 
|   28 if {!$MEMDEBUG} { |  | 
|   29    puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..." |  | 
|   30    finish_test |  | 
|   31    return |  | 
|   32 } |  | 
|   33  |  | 
|   34 # Do a couple of memory dumps just to exercise the memory dump logic |  | 
|   35 # that that we can say that we have. |  | 
|   36 # |  | 
|   37 puts stderr "This is a test.  Ignore the error that follows:" |  | 
|   38 sqlite3_memdebug_dump $testdir |  | 
|   39 puts "Memory dump to file memdump.txt..." |  | 
|   40 sqlite3_memdebug_dump memdump.txt |  | 
|   41  |  | 
|   42 ifcapable bloblit&&subquery { |  | 
|   43   do_malloc_test 1 -tclprep { |  | 
|   44     db close |  | 
|   45   } -tclbody { |  | 
|   46     if {[catch {sqlite3 db test.db}]} { |  | 
|   47       error "out of memory" |  | 
|   48     } |  | 
|   49     sqlite3_extended_result_codes db 1 |  | 
|   50   } -sqlbody { |  | 
|   51     DROP TABLE IF EXISTS t1; |  | 
|   52     CREATE TABLE t1( |  | 
|   53        a int, b float, c double, d text, e varchar(20), |  | 
|   54        primary key(a,b,c) |  | 
|   55     ); |  | 
|   56     CREATE INDEX i1 ON t1(a,b); |  | 
|   57     INSERT INTO t1 VALUES(1,2.3,4.5,'hi',x'746865726500'); |  | 
|   58     INSERT INTO t1 VALUES(6,7.0,0.8,'hello','out yonder'); |  | 
|   59     SELECT * FROM t1; |  | 
|   60     SELECT avg(b) FROM t1 GROUP BY a HAVING b>20.0; |  | 
|   61     DELETE FROM t1 WHERE a IN (SELECT min(a) FROM t1); |  | 
|   62     SELECT count(*), group_concat(e) FROM t1; |  | 
|   63     SELECT b FROM t1 ORDER BY 1 COLLATE nocase; |  | 
|   64   }  |  | 
|   65 } |  | 
|   66  |  | 
|   67 # Ensure that no file descriptors were leaked. |  | 
|   68 do_test malloc-1.X { |  | 
|   69   catch {db close} |  | 
|   70   set sqlite_open_file_count |  | 
|   71 } {0} |  | 
|   72  |  | 
|   73 ifcapable subquery { |  | 
|   74   do_malloc_test 2 -sqlbody { |  | 
|   75     CREATE TABLE t1(a int, b int default 'abc', c int default 1); |  | 
|   76     CREATE INDEX i1 ON t1(a,b); |  | 
|   77     INSERT INTO t1 VALUES(1,1,'99 abcdefghijklmnopqrstuvwxyz'); |  | 
|   78     INSERT INTO t1 VALUES(2,4,'98 abcdefghijklmnopqrstuvwxyz'); |  | 
|   79     INSERT INTO t1 VALUES(3,9,'97 abcdefghijklmnopqrstuvwxyz'); |  | 
|   80     INSERT INTO t1 VALUES(4,16,'96 abcdefghijklmnopqrstuvwxyz'); |  | 
|   81     INSERT INTO t1 VALUES(5,25,'95 abcdefghijklmnopqrstuvwxyz'); |  | 
|   82     INSERT INTO t1 VALUES(6,36,'94 abcdefghijklmnopqrstuvwxyz'); |  | 
|   83     SELECT 'stuff', count(*) as 'other stuff', max(a+10) FROM t1; |  | 
|   84     UPDATE t1 SET b=b||b||b||b; |  | 
|   85     UPDATE t1 SET b=a WHERE a in (10,12,22); |  | 
|   86     INSERT INTO t1(c,b,a) VALUES(20,10,5); |  | 
|   87     INSERT INTO t1 SELECT * FROM t1 |  | 
|   88         WHERE a IN (SELECT a FROM t1 WHERE a<10); |  | 
|   89     DELETE FROM t1 WHERE a>=10; |  | 
|   90     DROP INDEX i1; |  | 
|   91     DELETE FROM t1; |  | 
|   92   }  |  | 
|   93 } |  | 
|   94  |  | 
|   95 # Ensure that no file descriptors were leaked. |  | 
|   96 do_test malloc-2.X { |  | 
|   97   catch {db close} |  | 
|   98   set sqlite_open_file_count |  | 
|   99 } {0} |  | 
|  100  |  | 
|  101 do_malloc_test 3 -sqlbody { |  | 
|  102   BEGIN TRANSACTION; |  | 
|  103   CREATE TABLE t1(a int, b int, c int); |  | 
|  104   CREATE INDEX i1 ON t1(a,b); |  | 
|  105   INSERT INTO t1 VALUES(1,1,99); |  | 
|  106   INSERT INTO t1 VALUES(2,4,98); |  | 
|  107   INSERT INTO t1 VALUES(3,9,97); |  | 
|  108   INSERT INTO t1 VALUES(4,16,96); |  | 
|  109   INSERT INTO t1 VALUES(5,25,95); |  | 
|  110   INSERT INTO t1 VALUES(6,36,94); |  | 
|  111   INSERT INTO t1(c,b,a) VALUES(20,10,5); |  | 
|  112   DELETE FROM t1 WHERE a>=10; |  | 
|  113   DROP INDEX i1; |  | 
|  114   DELETE FROM t1; |  | 
|  115   ROLLBACK; |  | 
|  116 }  |  | 
|  117  |  | 
|  118  |  | 
|  119 # Ensure that no file descriptors were leaked. |  | 
|  120 do_test malloc-3.X { |  | 
|  121   catch {db close} |  | 
|  122   set sqlite_open_file_count |  | 
|  123 } {0} |  | 
|  124  |  | 
|  125 ifcapable subquery { |  | 
|  126   do_malloc_test 4 -sqlbody { |  | 
|  127     BEGIN TRANSACTION; |  | 
|  128     CREATE TABLE t1(a int, b int, c int); |  | 
|  129     CREATE INDEX i1 ON t1(a,b); |  | 
|  130     INSERT INTO t1 VALUES(1,1,99); |  | 
|  131     INSERT INTO t1 VALUES(2,4,98); |  | 
|  132     INSERT INTO t1 VALUES(3,9,97); |  | 
|  133     INSERT INTO t1 VALUES(4,16,96); |  | 
|  134     INSERT INTO t1 VALUES(5,25,95); |  | 
|  135     INSERT INTO t1 VALUES(6,36,94); |  | 
|  136     UPDATE t1 SET b=a WHERE a in (10,12,22); |  | 
|  137     INSERT INTO t1 SELECT * FROM t1 |  | 
|  138        WHERE a IN (SELECT a FROM t1 WHERE a<10); |  | 
|  139     DROP INDEX i1; |  | 
|  140     DELETE FROM t1; |  | 
|  141     COMMIT; |  | 
|  142   }  |  | 
|  143 } |  | 
|  144  |  | 
|  145 # Ensure that no file descriptors were leaked. |  | 
|  146 do_test malloc-4.X { |  | 
|  147   catch {db close} |  | 
|  148   set sqlite_open_file_count |  | 
|  149 } {0} |  | 
|  150  |  | 
|  151 ifcapable trigger { |  | 
|  152   do_malloc_test 5 -sqlbody { |  | 
|  153     BEGIN TRANSACTION; |  | 
|  154     CREATE TABLE t1(a,b); |  | 
|  155     CREATE TABLE t2(x,y); |  | 
|  156     CREATE TRIGGER r1 AFTER INSERT ON t1 WHEN new.a = 2 BEGIN |  | 
|  157       INSERT INTO t2(x,y) VALUES(new.rowid,1); |  | 
|  158       INSERT INTO t2(x,y) SELECT * FROM t2; |  | 
|  159       INSERT INTO t2 SELECT * FROM t2; |  | 
|  160       UPDATE t2 SET y=y+1 WHERE x=new.rowid; |  | 
|  161       SELECT 123; |  | 
|  162       DELETE FROM t2 WHERE x=new.rowid; |  | 
|  163     END; |  | 
|  164     INSERT INTO t1(a,b) VALUES(2,3); |  | 
|  165     COMMIT; |  | 
|  166   }  |  | 
|  167 } |  | 
|  168  |  | 
|  169 # Ensure that no file descriptors were leaked. |  | 
|  170 do_test malloc-5.X { |  | 
|  171   catch {db close} |  | 
|  172   set sqlite_open_file_count |  | 
|  173 } {0} |  | 
|  174  |  | 
|  175 ifcapable vacuum { |  | 
|  176   do_malloc_test 6 -sqlprep { |  | 
|  177     BEGIN TRANSACTION; |  | 
|  178     CREATE TABLE t1(a); |  | 
|  179     INSERT INTO t1 VALUES(1); |  | 
|  180     INSERT INTO t1 SELECT a*2 FROM t1; |  | 
|  181     INSERT INTO t1 SELECT a*2 FROM t1; |  | 
|  182     INSERT INTO t1 SELECT a*2 FROM t1; |  | 
|  183     INSERT INTO t1 SELECT a*2 FROM t1; |  | 
|  184     INSERT INTO t1 SELECT a*2 FROM t1; |  | 
|  185     INSERT INTO t1 SELECT a*2 FROM t1; |  | 
|  186     INSERT INTO t1 SELECT a*2 FROM t1; |  | 
|  187     INSERT INTO t1 SELECT a*2 FROM t1; |  | 
|  188     INSERT INTO t1 SELECT a*2 FROM t1; |  | 
|  189     INSERT INTO t1 SELECT a*2 FROM t1; |  | 
|  190     DELETE FROM t1 where rowid%5 = 0; |  | 
|  191     COMMIT; |  | 
|  192   } -sqlbody { |  | 
|  193     VACUUM; |  | 
|  194   }  |  | 
|  195 } |  | 
|  196  |  | 
|  197 autoinstall_test_functions |  | 
|  198 do_malloc_test 7 -sqlprep { |  | 
|  199   CREATE TABLE t1(a, b); |  | 
|  200   INSERT INTO t1 VALUES(1, 2); |  | 
|  201   INSERT INTO t1 VALUES(3, 4); |  | 
|  202   INSERT INTO t1 VALUES(5, 6); |  | 
|  203   INSERT INTO t1 VALUES(7, randstr(1200,1200)); |  | 
|  204 } -sqlbody { |  | 
|  205   SELECT min(a) FROM t1 WHERE a<6 GROUP BY b; |  | 
|  206   SELECT a FROM t1 WHERE a<6 ORDER BY a; |  | 
|  207   SELECT b FROM t1 WHERE a>6; |  | 
|  208 } |  | 
|  209  |  | 
|  210 # This block is designed to test that some malloc failures that may |  | 
|  211 # occur in vdbeapi.c. Specifically, if a malloc failure that occurs |  | 
|  212 # when converting UTF-16 text to integers and real numbers is handled |  | 
|  213 # correctly.  |  | 
|  214 # |  | 
|  215 # This is done by retrieving a string from the database engine and |  | 
|  216 # manipulating it using the sqlite3_column_*** APIs. This doesn't  |  | 
|  217 # actually return an error to the user when a malloc() fails.. That  |  | 
|  218 # could be viewed as a bug. |  | 
|  219 # |  | 
|  220 # These tests only run if UTF-16 support is compiled in. |  | 
|  221 # |  | 
|  222 ifcapable utf16 { |  | 
|  223   set ::STMT {} |  | 
|  224   do_malloc_test 8 -tclprep { |  | 
|  225     set sql "SELECT '[string repeat abc 20]', '[string repeat def 20]', ?" |  | 
|  226     set ::STMT [sqlite3_prepare db $sql -1 X] |  | 
|  227     sqlite3_step $::STMT |  | 
|  228     if { $::tcl_platform(byteOrder)=="littleEndian" } { |  | 
|  229       set ::bomstr "\xFF\xFE" |  | 
|  230     } else { |  | 
|  231       set ::bomstr "\xFE\xFF" |  | 
|  232     } |  | 
|  233     append ::bomstr [encoding convertto unicode "123456789_123456789_123456789"] |  | 
|  234   } -tclbody { |  | 
|  235     sqlite3_column_text16 $::STMT 0 |  | 
|  236     sqlite3_column_int $::STMT 0 |  | 
|  237     sqlite3_column_text16 $::STMT 1 |  | 
|  238     sqlite3_column_double $::STMT 1 |  | 
|  239     set rc [sqlite3_reset $::STMT] |  | 
|  240     if {$rc eq "SQLITE_NOMEM"} {error "out of memory"} |  | 
|  241     sqlite3_bind_text16 $::STMT 1 $::bomstr 60 |  | 
|  242     #catch {sqlite3_finalize $::STMT} |  | 
|  243     #if {[lindex [sqlite_malloc_stat] 2]<=0} { |  | 
|  244     #  error "out of memory" |  | 
|  245     #} |  | 
|  246   } -cleanup { |  | 
|  247     if {$::STMT!=""} { |  | 
|  248       sqlite3_finalize $::STMT |  | 
|  249       set ::STMT {} |  | 
|  250     } |  | 
|  251   } |  | 
|  252 } |  | 
|  253  |  | 
|  254 # This block tests that malloc() failures that occur whilst commiting |  | 
|  255 # a multi-file transaction are handled correctly. |  | 
|  256 # |  | 
|  257 do_malloc_test 9 -sqlprep { |  | 
|  258   ATTACH 'test2.db' as test2; |  | 
|  259   CREATE TABLE abc1(a, b, c); |  | 
|  260   CREATE TABLE test2.abc2(a, b, c); |  | 
|  261 } -sqlbody { |  | 
|  262   BEGIN; |  | 
|  263   INSERT INTO abc1 VALUES(1, 2, 3); |  | 
|  264   INSERT INTO abc2 VALUES(1, 2, 3); |  | 
|  265   COMMIT; |  | 
|  266 } |  | 
|  267  |  | 
|  268 # This block tests malloc() failures that occur while opening a  |  | 
|  269 # connection to a database. |  | 
|  270 do_malloc_test 10 -tclprep { |  | 
|  271   catch {db2 close} |  | 
|  272   db close |  | 
|  273   file delete -force test.db test.db-journal |  | 
|  274   sqlite3 db test.db |  | 
|  275   sqlite3_extended_result_codes db 1 |  | 
|  276   db eval {CREATE TABLE abc(a, b, c)} |  | 
|  277 } -tclbody { |  | 
|  278   db close |  | 
|  279   sqlite3 db2 test.db |  | 
|  280   sqlite3_extended_result_codes db2 1 |  | 
|  281   db2 eval {SELECT * FROM sqlite_master} |  | 
|  282   db2 close |  | 
|  283 } |  | 
|  284  |  | 
|  285 # This block tests malloc() failures that occur within calls to |  | 
|  286 # sqlite3_create_function(). |  | 
|  287 do_malloc_test 11 -tclbody { |  | 
|  288   set rc [sqlite3_create_function db] |  | 
|  289   if {[string match $rc SQLITE_OK]} { |  | 
|  290     set rc [sqlite3_create_aggregate db] |  | 
|  291   } |  | 
|  292   if {[string match $rc SQLITE_NOMEM]} { |  | 
|  293     error "out of memory" |  | 
|  294   } |  | 
|  295 } |  | 
|  296  |  | 
|  297 do_malloc_test 12 -tclbody { |  | 
|  298   set sql16 [encoding convertto unicode "SELECT * FROM sqlite_master"] |  | 
|  299   append sql16 "\00\00" |  | 
|  300   set ::STMT [sqlite3_prepare16 db $sql16 -1 DUMMY] |  | 
|  301   sqlite3_finalize $::STMT |  | 
|  302 } |  | 
|  303  |  | 
|  304 # Test malloc errors when replaying two hot journals from a 2-file  |  | 
|  305 # transaction. |  | 
|  306 ifcapable crashtest&&attach { |  | 
|  307   do_malloc_test 13 -tclprep { |  | 
|  308     set rc [crashsql -delay 1 -file test2.db { |  | 
|  309       ATTACH 'test2.db' as aux; |  | 
|  310       PRAGMA cache_size = 10; |  | 
|  311       BEGIN; |  | 
|  312       CREATE TABLE aux.t2(a, b, c); |  | 
|  313       CREATE TABLE t1(a, b, c); |  | 
|  314       COMMIT; |  | 
|  315     }] |  | 
|  316     if {$rc!="1 {child process exited abnormally}"} { |  | 
|  317       error "Wrong error message: $rc" |  | 
|  318     } |  | 
|  319   } -tclbody { |  | 
|  320     db eval {ATTACH 'test2.db' as aux;} |  | 
|  321     set rc [catch {db eval { |  | 
|  322       SELECT * FROM t1;  |  | 
|  323       SELECT * FROM t2; |  | 
|  324     }} err] |  | 
|  325     if {$rc && $err!="no such table: t1"} { |  | 
|  326       error $err |  | 
|  327     } |  | 
|  328   } |  | 
|  329 } |  | 
|  330  |  | 
|  331 if {$tcl_platform(platform)!="windows"} { |  | 
|  332   do_malloc_test 14 -tclprep { |  | 
|  333     catch {db close} |  | 
|  334     sqlite3 db2 test2.db |  | 
|  335     sqlite3_extended_result_codes db2 1 |  | 
|  336     db2 eval { |  | 
|  337       PRAGMA synchronous = 0; |  | 
|  338       CREATE TABLE t1(a, b); |  | 
|  339       INSERT INTO t1 VALUES(1, 2); |  | 
|  340       BEGIN; |  | 
|  341       INSERT INTO t1 VALUES(3, 4); |  | 
|  342     } |  | 
|  343     copy_file test2.db test.db |  | 
|  344     copy_file test2.db-journal test.db-journal |  | 
|  345     db2 close |  | 
|  346   } -tclbody { |  | 
|  347     sqlite3 db test.db |  | 
|  348     sqlite3_extended_result_codes db 1 |  | 
|  349  |  | 
|  350     # If an out-of-memory occurs within a call to a VFS layer function during |  | 
|  351     # hot-journal rollback, sqlite will report SQLITE_CORRUPT. See commit |  | 
|  352     # [5668] for details. |  | 
|  353     set rc [catch {db eval { SELECT * FROM t1 }} msg] |  | 
|  354     if {$msg eq "database disk image is malformed"} { set msg "out of memory" } |  | 
|  355     if {$rc} { error $msg } |  | 
|  356     set msg |  | 
|  357   } |  | 
|  358 } |  | 
|  359  |  | 
|  360 proc string_compare {a b} { |  | 
|  361   return [string compare $a $b] |  | 
|  362 } |  | 
|  363  |  | 
|  364 # Test for malloc() failures in sqlite3_create_collation() and  |  | 
|  365 # sqlite3_create_collation16(). |  | 
|  366 # |  | 
|  367 ifcapable utf16 { |  | 
|  368   do_malloc_test 15 -start 4 -tclbody { |  | 
|  369     db collate string_compare string_compare |  | 
|  370     if {[catch {add_test_collate db 1 1 1} msg]} { |  | 
|  371       if {$msg=="SQLITE_NOMEM"} {set msg "out of memory"} |  | 
|  372       error $msg |  | 
|  373     } |  | 
|  374    |  | 
|  375     db complete {SELECT "hello """||'world"' [microsoft], * FROM anicetable;} |  | 
|  376     db complete {-- Useful comment} |  | 
|  377    |  | 
|  378     execsql { |  | 
|  379       CREATE TABLE t1(a, b COLLATE string_compare); |  | 
|  380       INSERT INTO t1 VALUES(10, 'string'); |  | 
|  381       INSERT INTO t1 VALUES(10, 'string2'); |  | 
|  382     } |  | 
|  383   } |  | 
|  384 } |  | 
|  385  |  | 
|  386 # Also test sqlite3_complete(). There are (currently) no malloc() |  | 
|  387 # calls in this function, but test anyway against future changes. |  | 
|  388 # |  | 
|  389 do_malloc_test 16 -tclbody { |  | 
|  390   db complete {SELECT "hello """||'world"' [microsoft], * FROM anicetable;} |  | 
|  391   db complete {-- Useful comment} |  | 
|  392   db eval { |  | 
|  393     SELECT * FROM sqlite_master; |  | 
|  394   } |  | 
|  395 } |  | 
|  396  |  | 
|  397 # Test handling of malloc() failures in sqlite3_open16(). |  | 
|  398 # |  | 
|  399 ifcapable utf16 { |  | 
|  400   do_malloc_test 17 -tclbody { |  | 
|  401     set DB2 0 |  | 
|  402     set STMT 0 |  | 
|  403    |  | 
|  404     # open database using sqlite3_open16() |  | 
|  405     set filename [encoding convertto unicode test.db] |  | 
|  406     append filename "\x00\x00" |  | 
|  407     set DB2 [sqlite3_open16 $filename -unused] |  | 
|  408     if {0==$DB2} { |  | 
|  409       error "out of memory" |  | 
|  410     } |  | 
|  411     sqlite3_extended_result_codes $DB2 1 |  | 
|  412    |  | 
|  413     # Prepare statement |  | 
|  414     set rc [catch {sqlite3_prepare $DB2 {SELECT * FROM sqlite_master} -1 X} msg] |  | 
|  415     if {[sqlite3_errcode $DB2] eq "SQLITE_IOERR+12"} { |  | 
|  416       error "out of memory" |  | 
|  417     } |  | 
|  418     if {[regexp ".*automatic extension loading.*" [sqlite3_errmsg $DB2]]} { |  | 
|  419       error "out of memory" |  | 
|  420     } |  | 
|  421     if {$rc} { |  | 
|  422       error [string range $msg 4 end] |  | 
|  423     } |  | 
|  424     set STMT $msg |  | 
|  425    |  | 
|  426     # Finalize statement |  | 
|  427     set rc [sqlite3_finalize $STMT] |  | 
|  428     if {$rc!="SQLITE_OK"} { |  | 
|  429       error [sqlite3_errmsg $DB2] |  | 
|  430     } |  | 
|  431     set STMT 0 |  | 
|  432    |  | 
|  433     # Close database |  | 
|  434     set rc [sqlite3_close $DB2] |  | 
|  435     if {$rc!="SQLITE_OK"} { |  | 
|  436       error [sqlite3_errmsg $DB2] |  | 
|  437     } |  | 
|  438     set DB2 0 |  | 
|  439   } -cleanup { |  | 
|  440     if {$STMT!="0"} { |  | 
|  441       sqlite3_finalize $STMT |  | 
|  442     } |  | 
|  443     if {$DB2!="0"} { |  | 
|  444       set rc [sqlite3_close $DB2] |  | 
|  445     } |  | 
|  446   } |  | 
|  447 } |  | 
|  448  |  | 
|  449 # Test handling of malloc() failures in sqlite3_errmsg16(). |  | 
|  450 # |  | 
|  451 ifcapable utf16 { |  | 
|  452   do_malloc_test 18 -tclprep { |  | 
|  453     catch { |  | 
|  454       db eval "SELECT [string repeat longcolumnname 10] FROM sqlite_master" |  | 
|  455     } |  | 
|  456   } -tclbody { |  | 
|  457     set utf16 [sqlite3_errmsg16 [sqlite3_connection_pointer db]] |  | 
|  458     binary scan $utf16 c* bytes |  | 
|  459     if {[llength $bytes]==0} { |  | 
|  460       error "out of memory" |  | 
|  461     } |  | 
|  462   } |  | 
|  463 } |  | 
|  464  |  | 
|  465 # This test is aimed at coverage testing. Specificly, it is supposed to |  | 
|  466 # cause a malloc() only used when converting between the two utf-16  |  | 
|  467 # encodings to fail (i.e. little-endian->big-endian). It only actually  |  | 
|  468 # hits this malloc() on little-endian hosts. |  | 
|  469 # |  | 
|  470 set static_string "\x00h\x00e\x00l\x00l\x00o" |  | 
|  471 for {set l 0} {$l<10} {incr l} { |  | 
|  472   append static_string $static_string |  | 
|  473 } |  | 
|  474 append static_string "\x00\x00" |  | 
|  475 do_malloc_test 19 -tclprep { |  | 
|  476   execsql { |  | 
|  477     PRAGMA encoding = "UTF16be"; |  | 
|  478     CREATE TABLE abc(a, b, c); |  | 
|  479   } |  | 
|  480 } -tclbody { |  | 
|  481   unset -nocomplain ::STMT |  | 
|  482   set r [catch { |  | 
|  483     set ::STMT [sqlite3_prepare db {SELECT ?} -1 DUMMY] |  | 
|  484     sqlite3_bind_text16 -static $::STMT 1 $static_string 112 |  | 
|  485   } msg] |  | 
|  486   if {$r} {error [string range $msg 4 end]} |  | 
|  487   set msg |  | 
|  488 } -cleanup { |  | 
|  489   if {[info exists ::STMT]} { |  | 
|  490     sqlite3_finalize $::STMT |  | 
|  491   } |  | 
|  492 } |  | 
|  493 unset static_string |  | 
|  494  |  | 
|  495 # Make sure SQLITE_NOMEM is reported out on an ATTACH failure even |  | 
|  496 # when the malloc failure occurs within the nested parse. |  | 
|  497 # |  | 
|  498 ifcapable attach { |  | 
|  499   do_malloc_test 20 -tclprep { |  | 
|  500     db close |  | 
|  501     file delete -force test2.db test2.db-journal |  | 
|  502     sqlite3 db test2.db |  | 
|  503     sqlite3_extended_result_codes db 1 |  | 
|  504     db eval {CREATE TABLE t1(x);} |  | 
|  505     db close |  | 
|  506   } -tclbody { |  | 
|  507     if {[catch {sqlite3 db test.db}]} { |  | 
|  508       error "out of memory" |  | 
|  509     } |  | 
|  510     sqlite3_extended_result_codes db 1 |  | 
|  511   } -sqlbody { |  | 
|  512     ATTACH DATABASE 'test2.db' AS t2; |  | 
|  513     SELECT * FROM t1; |  | 
|  514     DETACH DATABASE t2; |  | 
|  515   }  |  | 
|  516 } |  | 
|  517  |  | 
|  518 # Test malloc failure whilst installing a foreign key. |  | 
|  519 # |  | 
|  520 ifcapable foreignkey { |  | 
|  521   do_malloc_test 21 -sqlbody { |  | 
|  522     CREATE TABLE abc(a, b, c, FOREIGN KEY(a) REFERENCES abc(b)) |  | 
|  523   }  |  | 
|  524 } |  | 
|  525  |  | 
|  526 # Test malloc failure in an sqlite3_prepare_v2() call. |  | 
|  527 # |  | 
|  528 do_malloc_test 22 -tclbody { |  | 
|  529   set ::STMT "" |  | 
|  530   set r [catch { |  | 
|  531     set ::STMT [ |  | 
|  532       sqlite3_prepare_v2 db "SELECT * FROM sqlite_master" -1 DUMMY |  | 
|  533     ] |  | 
|  534   } msg] |  | 
|  535   if {$r} {error [string range $msg 4 end]} |  | 
|  536 } -cleanup { |  | 
|  537   if {$::STMT ne ""} { |  | 
|  538     sqlite3_finalize $::STMT |  | 
|  539     set ::STMT "" |  | 
|  540   } |  | 
|  541 } |  | 
|  542  |  | 
|  543 ifcapable {pager_pragmas} { |  | 
|  544   # This tests a special case - that an error that occurs while the pager |  | 
|  545   # is trying to recover from error-state in exclusive-access mode works. |  | 
|  546   # |  | 
|  547   do_malloc_test 23 -tclprep { |  | 
|  548     db eval { |  | 
|  549       PRAGMA cache_size = 10; |  | 
|  550       PRAGMA locking_mode = exclusive; |  | 
|  551       BEGIN; |  | 
|  552       CREATE TABLE abc(a, b, c); |  | 
|  553       CREATE INDEX abc_i ON abc(a, b, c); |  | 
|  554       INSERT INTO abc  |  | 
|  555         VALUES(randstr(100,100), randstr(100,100), randstr(100,100)); |  | 
|  556       INSERT INTO abc  |  | 
|  557         SELECT randstr(100,100), randstr(100,100), randstr(100,100) FROM abc; |  | 
|  558       INSERT INTO abc  |  | 
|  559         SELECT randstr(100,100), randstr(100,100), randstr(100,100) FROM abc; |  | 
|  560       INSERT INTO abc  |  | 
|  561         SELECT randstr(100,100), randstr(100,100), randstr(100,100) FROM abc; |  | 
|  562       INSERT INTO abc  |  | 
|  563         SELECT randstr(100,100), randstr(100,100), randstr(100,100) FROM abc; |  | 
|  564       INSERT INTO abc  |  | 
|  565         SELECT randstr(100,100), randstr(100,100), randstr(100,100) FROM abc; |  | 
|  566       COMMIT; |  | 
|  567     } |  | 
|  568    |  | 
|  569     # This puts the pager into error state. |  | 
|  570     # |  | 
|  571     db eval BEGIN |  | 
|  572     db eval {UPDATE abc SET a = 0 WHERE oid%2} |  | 
|  573     set ::sqlite_io_error_pending 10 |  | 
|  574     catch {db eval {ROLLBACK}} msg |  | 
|  575  |  | 
|  576   } -tclbody { |  | 
|  577     # If an out-of-memory occurs within a call to a VFS layer function during |  | 
|  578     # hot-journal rollback, sqlite will report SQLITE_CORRUPT. See commit |  | 
|  579     # [5668] for details. |  | 
|  580     set rc [catch {db eval { SELECT * FROM abc LIMIT 10 }} msg] |  | 
|  581     if {$msg eq "database disk image is malformed"} { set msg "out of memory" } |  | 
|  582     if {$rc} { error $msg } |  | 
|  583     set msg |  | 
|  584   } -cleanup { |  | 
|  585     set e [db eval {PRAGMA integrity_check}] |  | 
|  586     if {$e ne "ok"} {error $e} |  | 
|  587   } |  | 
|  588 } |  | 
|  589  |  | 
|  590 ifcapable compound { |  | 
|  591   do_malloc_test 24 -sqlprep { |  | 
|  592     CREATE TABLE t1(a, b, c) |  | 
|  593   } -sqlbody { |  | 
|  594     SELECT 1 FROM t1 UNION SELECT 2 FROM t1 ORDER BY 1 |  | 
|  595   } |  | 
|  596 } |  | 
|  597  |  | 
|  598 ifcapable view&&trigger { |  | 
|  599   do_malloc_test 25 -sqlprep { |  | 
|  600     CREATE TABLE t1(a, b, c); |  | 
|  601     CREATE VIEW v1 AS SELECT * FROM t1; |  | 
|  602     CREATE TRIGGER v1t1 INSTEAD OF DELETE ON v1 BEGIN SELECT 1; END; |  | 
|  603     CREATE TRIGGER v1t2 INSTEAD OF INSERT ON v1 BEGIN SELECT 1; END; |  | 
|  604     CREATE TRIGGER v1t3 INSTEAD OF UPDATE ON v1 BEGIN SELECT 1; END; |  | 
|  605   } -sqlbody { |  | 
|  606     DELETE FROM v1 WHERE a = 1; |  | 
|  607     INSERT INTO v1 VALUES(1, 2, 3); |  | 
|  608     UPDATE v1 SET a = 1 WHERE b = 2; |  | 
|  609   } |  | 
|  610 } |  | 
|  611  |  | 
|  612 do_malloc_test 25 -sqlprep { |  | 
|  613   CREATE TABLE abc(a, b, c); |  | 
|  614   CREATE INDEX i1 ON abc(a, b); |  | 
|  615   INSERT INTO abc VALUES(1, 2, 3); |  | 
|  616   INSERT INTO abc VALUES(4, 5, 6); |  | 
|  617 } -tclbody { |  | 
|  618   # For each UPDATE executed, the cursor used for the SELECT statement |  | 
|  619   # must be "saved". Because the cursor is open on an index, this requires |  | 
|  620   # a malloc() to allocate space to save the index key. This test case is |  | 
|  621   # aimed at testing the response of the library to a failure in that |  | 
|  622   # particular malloc() call. |  | 
|  623   db eval {SELECT a FROM abc ORDER BY a} { |  | 
|  624     db eval {UPDATE abc SET b = b - 1 WHERE a = $a} |  | 
|  625   } |  | 
|  626 } |  | 
|  627  |  | 
|  628 # This test is designed to test a specific juncture in the sqlite code. |  | 
|  629 # The database set up by -sqlprep script contains a single table B-Tree |  | 
|  630 # of height 2. In the -tclbody script, the existing database connection |  | 
|  631 # is closed and a new one opened and used to insert a new row into the |  | 
|  632 # table B-Tree. By using a new connection, the outcome of a malloc()  |  | 
|  633 # failure while seeking to the right-hand side of the B-Tree to insert  |  | 
|  634 # a new record can be tested. |  | 
|  635 # |  | 
|  636 do_malloc_test 26 -sqlprep { |  | 
|  637   BEGIN; |  | 
|  638   CREATE TABLE t1(a, b); |  | 
|  639   INSERT INTO t1 VALUES(1, randomblob(210)); |  | 
|  640   INSERT INTO t1 VALUES(1, randomblob(210)); |  | 
|  641   INSERT INTO t1 VALUES(1, randomblob(210)); |  | 
|  642   INSERT INTO t1 VALUES(1, randomblob(210)); |  | 
|  643   INSERT INTO t1 VALUES(1, randomblob(210)); |  | 
|  644   COMMIT; |  | 
|  645 } -tclbody { |  | 
|  646   db close |  | 
|  647   sqlite3 db test.db |  | 
|  648   db eval { INSERT INTO t1 VALUES(1, randomblob(210)) } |  | 
|  649 } |  | 
|  650  |  | 
|  651 # Test that no memory is leaked following a malloc() failure in |  | 
|  652 # sqlite3_initialize(). |  | 
|  653 # |  | 
|  654 do_malloc_test 27 -tclprep { |  | 
|  655   db close |  | 
|  656   sqlite3_shutdown |  | 
|  657 } -tclbody { |  | 
|  658   set rc [sqlite3_initialize] |  | 
|  659   if {$rc == "SQLITE_NOMEM"} { |  | 
|  660     error "out of memory" |  | 
|  661   } |  | 
|  662 } |  | 
|  663 autoinstall_test_functions |  | 
|  664  |  | 
|  665 # Test that malloc failures that occur while processing INDEXED BY |  | 
|  666 # clauses are handled correctly. |  | 
|  667 do_malloc_test 28 -sqlprep { |  | 
|  668   CREATE TABLE t1(a, b); |  | 
|  669   CREATE INDEX i1 ON t1(a); |  | 
|  670   CREATE VIEW v1 AS SELECT * FROM t1 INDEXED BY i1 WHERE a = 10; |  | 
|  671 } -sqlbody { |  | 
|  672   SELECT * FROM t1 INDEXED BY i1 ORDER BY a; |  | 
|  673   SELECT * FROM v1; |  | 
|  674 } |  | 
|  675  |  | 
|  676 do_malloc_test 29 -sqlprep { |  | 
|  677   CREATE TABLE t1(a TEXT, b TEXT); |  | 
|  678 } -sqlbody { |  | 
|  679   INSERT INTO t1 VALUES(1, -234); |  | 
|  680   INSERT INTO t1 SELECT * FROM t1 UNION ALL SELECT * FROM t1; |  | 
|  681 } |  | 
|  682  |  | 
|  683 do_malloc_test 30 -tclprep { |  | 
|  684   db eval { |  | 
|  685     CREATE TABLE t1(x PRIMARY KEY); |  | 
|  686     INSERT INTO t1 VALUES(randstr(500,500)); |  | 
|  687     INSERT INTO t1 VALUES(randstr(500,500)); |  | 
|  688     INSERT INTO t1 VALUES(randstr(500,500)); |  | 
|  689   } |  | 
|  690   db close |  | 
|  691   sqlite3 db test.db |  | 
|  692  |  | 
|  693   # The DELETE command in the following block moves the overflow pages that |  | 
|  694   # are part of the primary key index to the free-list. But it does not |  | 
|  695   # actually load the content of the pages. This leads to the peculiar |  | 
|  696   # situation where cache entries exist, but are not populated with data. |  | 
|  697   # They are populated next time they are requested by the b-tree layer. |  | 
|  698   # |  | 
|  699   db eval { |  | 
|  700     BEGIN; |  | 
|  701       DELETE FROM t1; |  | 
|  702     ROLLBACK; |  | 
|  703   } |  | 
|  704 } -sqlbody { |  | 
|  705   -- This statement requires the 'no-content' pages loaded by the DELETE |  | 
|  706   -- statement above. When requesting the pages, the content is loaded |  | 
|  707   -- from the database file. The point of this test case is to test handling |  | 
|  708   -- of malloc errors (including SQLITE_IOERR_NOMEM errors) when loading |  | 
|  709   -- the content. |  | 
|  710   SELECT * FROM t1 ORDER BY x; |  | 
|  711 } |  | 
|  712  |  | 
|  713 # After committing a transaction in persistent-journal mode, if a journal |  | 
|  714 # size limit is configured SQLite may attempt to truncate the journal file. |  | 
|  715 # This test verifies the libraries response to a malloc() failure during |  | 
|  716 # this operation. |  | 
|  717 # |  | 
|  718 do_malloc_test 31 -sqlprep { |  | 
|  719   PRAGMA journal_mode = persist; |  | 
|  720   PRAGMA journal_size_limit = 1024; |  | 
|  721   CREATE TABLE t1(a PRIMARY KEY, b); |  | 
|  722 } -sqlbody { |  | 
|  723   INSERT INTO t1 VALUES(1, 2); |  | 
|  724 } |  | 
|  725  |  | 
|  726 # When written, this test provoked an obscure change-counter bug. |  | 
|  727 #  |  | 
|  728 # If, when running in exclusive mode, a malloc() failure occurs |  | 
|  729 # after the database file change-counter has been written but |  | 
|  730 # before the transaction has been committed, then the transaction |  | 
|  731 # is automatically rolled back. However, internally the  |  | 
|  732 # Pager.changeCounterDone flag was being left set. This means |  | 
|  733 # that if the same connection attempts another transaction following |  | 
|  734 # the malloc failure and rollback, the change counter will not |  | 
|  735 # be updated. This could corrupt another processes cache. |  | 
|  736 # |  | 
|  737 do_malloc_test 32 -tclprep { |  | 
|  738   # Build a small database containing an indexed table. |  | 
|  739   # |  | 
|  740   db eval { |  | 
|  741     PRAGMA locking_mode = normal; |  | 
|  742     BEGIN; |  | 
|  743     CREATE TABLE t1(a PRIMARY KEY, b); |  | 
|  744     INSERT INTO t1 VALUES(1, 'one'); |  | 
|  745     INSERT INTO t1 VALUES(2, 'two'); |  | 
|  746     INSERT INTO t1 VALUES(3, 'three'); |  | 
|  747     COMMIT; |  | 
|  748     PRAGMA locking_mode = exclusive; |  | 
|  749   } |  | 
|  750  |  | 
|  751   # Open a second database connection. Load the table (but not index) |  | 
|  752   # into the second connections pager cache. |  | 
|  753   # |  | 
|  754   sqlite3 db2 test.db |  | 
|  755   db2 eval {  |  | 
|  756     PRAGMA locking_mode = normal; |  | 
|  757     SELECT b FROM t1; |  | 
|  758   } |  | 
|  759  |  | 
|  760 } -tclbody { |  | 
|  761   # Running in exclusive mode, perform a database transaction that  |  | 
|  762   # modifies both the database table and index. For iterations where |  | 
|  763   # the malloc failure occurs after updating the change counter but |  | 
|  764   # before committing the transaction, this should result in the |  | 
|  765   # transaction being rolled back but the changeCounterDone flag |  | 
|  766   # left set. |  | 
|  767   # |  | 
|  768   db eval { UPDATE t1 SET a = a + 3 } |  | 
|  769 } -cleanup { |  | 
|  770  |  | 
|  771   # Perform another transaction using the first connection. Unlock |  | 
|  772   # the database after doing so. If this is one of the right iterations, |  | 
|  773   # then this should result in the database contents being updated but |  | 
|  774   # the change-counter left as it is. |  | 
|  775   # |  | 
|  776   db eval {  |  | 
|  777     PRAGMA locking_mode = normal; |  | 
|  778     UPDATE t1 SET a = a + 3; |  | 
|  779   } |  | 
|  780  |  | 
|  781   # Now do an integrity check with the second connection. The second |  | 
|  782   # connection still has the database table in its cache. If this is |  | 
|  783   # one of the magic iterations and the change counter was not modified, |  | 
|  784   # then it won't realize that the cached data is out of date. Since |  | 
|  785   # the cached data won't match the up to date index data read from |  | 
|  786   # the database file, the integrity check should fail. |  | 
|  787   # |  | 
|  788   set zRepeat "transient" |  | 
|  789   if {$::iRepeat} {set zRepeat "persistent"} |  | 
|  790   do_test malloc-32.$zRepeat.${::n}.integrity { |  | 
|  791     execsql {PRAGMA integrity_check} db2 |  | 
|  792   } {ok} |  | 
|  793   db2 close |  | 
|  794 } |  | 
|  795  |  | 
|  796 # The following two OOM tests verify that OOM handling works in the |  | 
|  797 # code used to optimize "SELECT count(*) FROM <tbl>". |  | 
|  798 # |  | 
|  799 do_malloc_test 33 -tclprep { |  | 
|  800   db eval { PRAGMA cache_size = 10 } |  | 
|  801   db transaction { |  | 
|  802     db eval { CREATE TABLE abc(a, b) } |  | 
|  803     for {set i 0} {$i<500} {incr i} { |  | 
|  804       db eval {INSERT INTO abc VALUES(randstr(100,100), randstr(1000,1000))} |  | 
|  805     } |  | 
|  806   } |  | 
|  807 } -sqlbody { |  | 
|  808   SELECT count(*) FROM abc; |  | 
|  809 } |  | 
|  810 do_malloc_test 34 -tclprep { |  | 
|  811   db eval { PRAGMA cache_size = 10 } |  | 
|  812   db transaction { |  | 
|  813     db eval { CREATE TABLE abc(a PRIMARY KEY, b) } |  | 
|  814     for {set i 0} {$i<500} {incr i} { |  | 
|  815       db eval {INSERT INTO abc VALUES(randstr(100,100), randstr(1000,1000))} |  | 
|  816     } |  | 
|  817   } |  | 
|  818 } -sqlbody { |  | 
|  819   SELECT count(*) FROM abc; |  | 
|  820 } |  | 
|  821  |  | 
|  822 proc f {args} { error "Quite a long error!" } |  | 
|  823 do_malloc_test 35 -tclprep { |  | 
|  824   db func f f |  | 
|  825   set ::STMT [sqlite3_prepare db "SELECT f()" -1 DUMMY] |  | 
|  826   sqlite3_step $::STMT |  | 
|  827 } -tclbody { |  | 
|  828   sqlite3_finalize $::STMT |  | 
|  829 } -cleanup { |  | 
|  830   # At one point an assert( !db->mallocFailed ) could fail in the following |  | 
|  831   # call to sqlite3_errmsg(). Because sqlite3_finalize() had failed to clear |  | 
|  832   # the flag before returning. |  | 
|  833   sqlite3_errmsg16 db |  | 
|  834 } |  | 
|  835  |  | 
|  836 do_malloc_test 36 -sqlprep { |  | 
|  837   CREATE TABLE t1(a, b); |  | 
|  838   INSERT INTO t1 VALUES(1, 2); |  | 
|  839   INSERT INTO t1 VALUES(3, 4); |  | 
|  840 } -sqlbody { |  | 
|  841   SELECT test_agg_errmsg16(), group_concat(a) FROM t1 |  | 
|  842 } |  | 
|  843  |  | 
|  844 # At one point, if an OOM occured immediately after obtaining a shared lock |  | 
|  845 # on the database file, the file remained locked. This test case ensures |  | 
|  846 # that bug has been fixed.i |  | 
|  847 if {[db eval {PRAGMA locking_mode}]!="exclusive"} { |  | 
|  848   do_malloc_test 37 -tclprep { |  | 
|  849     sqlite3 db2 test.db |  | 
|  850     execsql { |  | 
|  851       CREATE TABLE t1(a, b); |  | 
|  852       INSERT INTO t1 VALUES(1, 2); |  | 
|  853     } db2 |  | 
|  854   } -sqlbody { |  | 
|  855     SELECT * FROM t1; |  | 
|  856   } -cleanup { |  | 
|  857     # Try to write to the database using connection [db2]. If connection [db] |  | 
|  858     # has correctly released the shared lock, this write attempt should  |  | 
|  859     # succeed. If [db] has not released the lock, this should hit an  |  | 
|  860     # SQLITE_BUSY error. |  | 
|  861     do_test malloc-36.$zRepeat.${::n}.unlocked { |  | 
|  862       execsql {INSERT INTO t1 VALUES(3, 4)} db2 |  | 
|  863     } {} |  | 
|  864     db2 close |  | 
|  865   } |  | 
|  866   catch { db2 close } |  | 
|  867 } |  | 
|  868  |  | 
|  869 ifcapable stat2 { |  | 
|  870   do_malloc_test 38 -tclprep { |  | 
|  871     add_test_collate db 0 0 1 |  | 
|  872     execsql { |  | 
|  873       ANALYZE; |  | 
|  874       CREATE TABLE t4(x COLLATE test_collate); |  | 
|  875       CREATE INDEX t4x ON t4(x); |  | 
|  876       INSERT INTO sqlite_stat2 VALUES('t4', 't4x', 0, 'aaa'); |  | 
|  877       INSERT INTO sqlite_stat2 VALUES('t4', 't4x', 1, 'aaa'); |  | 
|  878       INSERT INTO sqlite_stat2 VALUES('t4', 't4x', 2, 'aaa'); |  | 
|  879       INSERT INTO sqlite_stat2 VALUES('t4', 't4x', 3, 'aaa'); |  | 
|  880       INSERT INTO sqlite_stat2 VALUES('t4', 't4x', 4, 'aaa'); |  | 
|  881       INSERT INTO sqlite_stat2 VALUES('t4', 't4x', 5, 'aaa'); |  | 
|  882       INSERT INTO sqlite_stat2 VALUES('t4', 't4x', 6, 'aaa'); |  | 
|  883       INSERT INTO sqlite_stat2 VALUES('t4', 't4x', 7, 'aaa'); |  | 
|  884       INSERT INTO sqlite_stat2 VALUES('t4', 't4x', 8, 'aaa'); |  | 
|  885       INSERT INTO sqlite_stat2 VALUES('t4', 't4x', 9, 'aaa'); |  | 
|  886     } |  | 
|  887     db close |  | 
|  888     sqlite3 db test.db |  | 
|  889     sqlite3_db_config_lookaside db 0 0 0 |  | 
|  890     add_test_collate db 0 0 1 |  | 
|  891   } -sqlbody { |  | 
|  892     SELECT * FROM t4 AS t41, t4 AS t42 WHERE t41.x>'ddd' AND t42.x>'ccc' |  | 
|  893   } |  | 
|  894 } |  | 
|  895  |  | 
|  896 # Ensure that no file descriptors were leaked. |  | 
|  897 do_test malloc-99.X { |  | 
|  898   catch {db close} |  | 
|  899   set sqlite_open_file_count |  | 
|  900 } {0} |  | 
|  901  |  | 
|  902 puts open-file-count=$sqlite_open_file_count |  | 
|  903 finish_test |  | 
| OLD | NEW |