1b19a2bc6Sdrh# 2001 September 15 2ed7c855cSdrh# 3b19a2bc6Sdrh# The author disclaims copyright to this source code. In place of 4b19a2bc6Sdrh# a legal notice, here is a blessing: 5ed7c855cSdrh# 6b19a2bc6Sdrh# May you do good and not evil. 7b19a2bc6Sdrh# May you find forgiveness for yourself and forgive others. 8b19a2bc6Sdrh# May you share freely, never taking more than you give. 9ed7c855cSdrh# 10ed7c855cSdrh#*********************************************************************** 11ed7c855cSdrh# This file attempts to check the library in an out-of-memory situation. 12c89b91beSdrh# When compiled with -DSQLITE_DEBUG=1, the SQLite library accepts a special 136d4abfbeSdrh# command (sqlite_malloc_fail N) which causes the N-th malloc to fail. This 14ed7c855cSdrh# special feature is used to see what happens in the library if a malloc 15ed7c855cSdrh# were to really fail due to an out-of-memory situation. 16ed7c855cSdrh# 17*c9cf901dSdanielk1977# $Id: malloc.test,v 1.42 2007/05/30 10:36:47 danielk1977 Exp $ 18ed7c855cSdrh 19ed7c855cSdrhset testdir [file dirname $argv0] 20ed7c855cSdrhsource $testdir/tester.tcl 21ed7c855cSdrh 22ed7c855cSdrh# Only run these tests if memory debugging is turned on. 23ed7c855cSdrh# 24b5f70c2eSdrhif {[info command sqlite_malloc_stat]==""} { 25261919ccSdanielk1977 puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..." 26ed7c855cSdrh finish_test 27ed7c855cSdrh return 28ed7c855cSdrh} 29ed7c855cSdrh 30*c9cf901dSdanielk1977source $testdir/malloc_common.tcl 314397de57Sdanielk1977 32c08d405dSdanielk1977do_malloc_test 1 -tclprep { 33c08d405dSdanielk1977 db close 34c08d405dSdanielk1977} -tclbody { 35c08d405dSdanielk1977 if {[catch {sqlite3 db test.db}]} { 36c08d405dSdanielk1977 error "out of memory" 37c08d405dSdanielk1977 } 38c08d405dSdanielk1977} -sqlbody { 39344a6276Sdrh DROP TABLE IF EXISTS t1; 40ed7c855cSdrh CREATE TABLE t1( 41ed7c855cSdrh a int, b float, c double, d text, e varchar(20), 42ed7c855cSdrh primary key(a,b,c) 43ed7c855cSdrh ); 44ed7c855cSdrh CREATE INDEX i1 ON t1(a,b); 4576f80796Sdrh INSERT INTO t1 VALUES(1,2.3,4.5,'hi',x'746865726500'); 46ed7c855cSdrh INSERT INTO t1 VALUES(6,7.0,0.8,'hello','out yonder'); 47ed7c855cSdrh SELECT * FROM t1; 48d400728aSdrh SELECT avg(b) FROM t1 GROUP BY a HAVING b>20.0; 496d4abfbeSdrh DELETE FROM t1 WHERE a IN (SELECT min(a) FROM t1); 50ed7c855cSdrh SELECT count(*) FROM t1; 51ed7c855cSdrh} 52d400728aSdrh 53b5548a8bSdanielk1977# Ensure that no file descriptors were leaked. 54b5548a8bSdanielk1977do_test malloc-1.X { 55b5548a8bSdanielk1977 catch {db close} 56b5548a8bSdanielk1977 set sqlite_open_file_count 57b5548a8bSdanielk1977} {0} 58b5548a8bSdanielk1977 59c08d405dSdanielk1977do_malloc_test 2 -sqlbody { 60fc23314aSdrh CREATE TABLE t1(a int, b int default 'abc', c int default 1); 61d400728aSdrh CREATE INDEX i1 ON t1(a,b); 625f3b4ab5Sdrh INSERT INTO t1 VALUES(1,1,'99 abcdefghijklmnopqrstuvwxyz'); 635f3b4ab5Sdrh INSERT INTO t1 VALUES(2,4,'98 abcdefghijklmnopqrstuvwxyz'); 645f3b4ab5Sdrh INSERT INTO t1 VALUES(3,9,'97 abcdefghijklmnopqrstuvwxyz'); 655f3b4ab5Sdrh INSERT INTO t1 VALUES(4,16,'96 abcdefghijklmnopqrstuvwxyz'); 665f3b4ab5Sdrh INSERT INTO t1 VALUES(5,25,'95 abcdefghijklmnopqrstuvwxyz'); 675f3b4ab5Sdrh INSERT INTO t1 VALUES(6,36,'94 abcdefghijklmnopqrstuvwxyz'); 686d4abfbeSdrh SELECT 'stuff', count(*) as 'other stuff', max(a+10) FROM t1; 696d4abfbeSdrh UPDATE t1 SET b=b||b||b||b; 70d400728aSdrh UPDATE t1 SET b=a WHERE a in (10,12,22); 716d4abfbeSdrh INSERT INTO t1(c,b,a) VALUES(20,10,5); 726d4abfbeSdrh INSERT INTO t1 SELECT * FROM t1 736d4abfbeSdrh WHERE a IN (SELECT a FROM t1 WHERE a<10); 746d4abfbeSdrh DELETE FROM t1 WHERE a>=10; 75d400728aSdrh DROP INDEX i1; 766d4abfbeSdrh DELETE FROM t1; 776d4abfbeSdrh} 786d4abfbeSdrh 79b5548a8bSdanielk1977# Ensure that no file descriptors were leaked. 80b5548a8bSdanielk1977do_test malloc-2.X { 81b5548a8bSdanielk1977 catch {db close} 82b5548a8bSdanielk1977 set sqlite_open_file_count 83b5548a8bSdanielk1977} {0} 84b5548a8bSdanielk1977 85c08d405dSdanielk1977do_malloc_test 3 -sqlbody { 866d4abfbeSdrh BEGIN TRANSACTION; 876d4abfbeSdrh CREATE TABLE t1(a int, b int, c int); 886d4abfbeSdrh CREATE INDEX i1 ON t1(a,b); 895f3b4ab5Sdrh INSERT INTO t1 VALUES(1,1,99); 905f3b4ab5Sdrh INSERT INTO t1 VALUES(2,4,98); 915f3b4ab5Sdrh INSERT INTO t1 VALUES(3,9,97); 925f3b4ab5Sdrh INSERT INTO t1 VALUES(4,16,96); 935f3b4ab5Sdrh INSERT INTO t1 VALUES(5,25,95); 945f3b4ab5Sdrh INSERT INTO t1 VALUES(6,36,94); 956d4abfbeSdrh INSERT INTO t1(c,b,a) VALUES(20,10,5); 966d4abfbeSdrh DELETE FROM t1 WHERE a>=10; 976d4abfbeSdrh DROP INDEX i1; 986d4abfbeSdrh DELETE FROM t1; 996d4abfbeSdrh ROLLBACK; 1006d4abfbeSdrh} 101c08d405dSdanielk1977 102b5548a8bSdanielk1977 103b5548a8bSdanielk1977# Ensure that no file descriptors were leaked. 104b5548a8bSdanielk1977do_test malloc-3.X { 105b5548a8bSdanielk1977 catch {db close} 106b5548a8bSdanielk1977 set sqlite_open_file_count 107b5548a8bSdanielk1977} {0} 108b5548a8bSdanielk1977 109c08d405dSdanielk1977do_malloc_test 4 -sqlbody { 1106d4abfbeSdrh BEGIN TRANSACTION; 1116d4abfbeSdrh CREATE TABLE t1(a int, b int, c int); 1126d4abfbeSdrh CREATE INDEX i1 ON t1(a,b); 1135f3b4ab5Sdrh INSERT INTO t1 VALUES(1,1,99); 1145f3b4ab5Sdrh INSERT INTO t1 VALUES(2,4,98); 1155f3b4ab5Sdrh INSERT INTO t1 VALUES(3,9,97); 1165f3b4ab5Sdrh INSERT INTO t1 VALUES(4,16,96); 1175f3b4ab5Sdrh INSERT INTO t1 VALUES(5,25,95); 1185f3b4ab5Sdrh INSERT INTO t1 VALUES(6,36,94); 1196d4abfbeSdrh UPDATE t1 SET b=a WHERE a in (10,12,22); 1206d4abfbeSdrh INSERT INTO t1 SELECT * FROM t1 1216d4abfbeSdrh WHERE a IN (SELECT a FROM t1 WHERE a<10); 1226d4abfbeSdrh DROP INDEX i1; 1236d4abfbeSdrh DELETE FROM t1; 1246d4abfbeSdrh COMMIT; 125d400728aSdrh} 126b5548a8bSdanielk1977 127b5548a8bSdanielk1977# Ensure that no file descriptors were leaked. 128b5548a8bSdanielk1977do_test malloc-4.X { 129b5548a8bSdanielk1977 catch {db close} 130b5548a8bSdanielk1977 set sqlite_open_file_count 131b5548a8bSdanielk1977} {0} 132b5548a8bSdanielk1977 133c08d405dSdanielk1977do_malloc_test 5 -sqlbody { 134e4697f5eSdrh BEGIN TRANSACTION; 135e4697f5eSdrh CREATE TABLE t1(a,b); 136e4697f5eSdrh CREATE TABLE t2(x,y); 137e4697f5eSdrh CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN 138e4697f5eSdrh INSERT INTO t2(x,y) VALUES(new.rowid,1); 13928f45914Sdrh UPDATE t2 SET y=y+1 WHERE x=new.rowid; 14028f45914Sdrh SELECT 123; 14128f45914Sdrh DELETE FROM t2 WHERE x=new.rowid; 142e4697f5eSdrh END; 143e4697f5eSdrh INSERT INTO t1(a,b) VALUES(2,3); 144e4697f5eSdrh COMMIT; 145e4697f5eSdrh} 146b5548a8bSdanielk1977 147b5548a8bSdanielk1977# Ensure that no file descriptors were leaked. 148b5548a8bSdanielk1977do_test malloc-5.X { 149b5548a8bSdanielk1977 catch {db close} 150b5548a8bSdanielk1977 set sqlite_open_file_count 151b5548a8bSdanielk1977} {0} 152b5548a8bSdanielk1977 153c08d405dSdanielk1977do_malloc_test 6 -sqlprep { 15496fb0dd5Sdanielk1977 BEGIN TRANSACTION; 15596fb0dd5Sdanielk1977 CREATE TABLE t1(a); 15696fb0dd5Sdanielk1977 INSERT INTO t1 VALUES(1); 15796fb0dd5Sdanielk1977 INSERT INTO t1 SELECT a*2 FROM t1; 15896fb0dd5Sdanielk1977 INSERT INTO t1 SELECT a*2 FROM t1; 15996fb0dd5Sdanielk1977 INSERT INTO t1 SELECT a*2 FROM t1; 16096fb0dd5Sdanielk1977 INSERT INTO t1 SELECT a*2 FROM t1; 16196fb0dd5Sdanielk1977 INSERT INTO t1 SELECT a*2 FROM t1; 16296fb0dd5Sdanielk1977 INSERT INTO t1 SELECT a*2 FROM t1; 16396fb0dd5Sdanielk1977 INSERT INTO t1 SELECT a*2 FROM t1; 16496fb0dd5Sdanielk1977 INSERT INTO t1 SELECT a*2 FROM t1; 16596fb0dd5Sdanielk1977 INSERT INTO t1 SELECT a*2 FROM t1; 16696fb0dd5Sdanielk1977 INSERT INTO t1 SELECT a*2 FROM t1; 16796fb0dd5Sdanielk1977 DELETE FROM t1 where rowid%5 = 0; 16896fb0dd5Sdanielk1977 COMMIT; 169c08d405dSdanielk1977} -sqlbody { 17096fb0dd5Sdanielk1977 VACUUM; 17196fb0dd5Sdanielk1977} 17296fb0dd5Sdanielk1977 173c08d405dSdanielk1977do_malloc_test 7 -sqlprep { 17401427a62Sdanielk1977 CREATE TABLE t1(a, b); 17501427a62Sdanielk1977 INSERT INTO t1 VALUES(1, 2); 17601427a62Sdanielk1977 INSERT INTO t1 VALUES(3, 4); 17701427a62Sdanielk1977 INSERT INTO t1 VALUES(5, 6); 178b5402fbfSdanielk1977 INSERT INTO t1 VALUES(7, randstr(1200,1200)); 179c08d405dSdanielk1977} -sqlbody { 180b5402fbfSdanielk1977 SELECT min(a) FROM t1 WHERE a<6 GROUP BY b; 181b5402fbfSdanielk1977 SELECT a FROM t1 WHERE a<6 ORDER BY a; 182b5402fbfSdanielk1977 SELECT b FROM t1 WHERE a>6; 18301427a62Sdanielk1977} 18401427a62Sdanielk1977 185b5402fbfSdanielk1977# This block is designed to test that some malloc failures that may 186b5402fbfSdanielk1977# occur in vdbeapi.c. Specifically, if a malloc failure that occurs 187b5402fbfSdanielk1977# when converting UTF-16 text to integers and real numbers is handled 188b5402fbfSdanielk1977# correctly. 189b5402fbfSdanielk1977# 1908b60e0f1Sdanielk1977# This is done by retrieving a string from the database engine and 1918b60e0f1Sdanielk1977# manipulating it using the sqlite3_column_*** APIs. This doesn't 1928b60e0f1Sdanielk1977# actually return an error to the user when a malloc() fails.. That 1938b60e0f1Sdanielk1977# could be viewed as a bug. 1948b60e0f1Sdanielk1977# 1958b60e0f1Sdanielk1977# These tests only run if UTF-16 support is compiled in. 196b5402fbfSdanielk1977# 197c08d405dSdanielk1977if {$::sqlite_options(utf16)} { 198c08d405dSdanielk1977 do_malloc_test 8 -tclprep { 199b5402fbfSdanielk1977 set sql "SELECT '[string repeat abc 20]', '[string repeat def 20]', ?" 200b5402fbfSdanielk1977 set ::STMT [sqlite3_prepare $::DB $sql -1 X] 201b5402fbfSdanielk1977 sqlite3_step $::STMT 202b5402fbfSdanielk1977 if { $::tcl_platform(byteOrder)=="littleEndian" } { 203b5402fbfSdanielk1977 set ::bomstr "\xFF\xFE" 204b5402fbfSdanielk1977 } else { 205b5402fbfSdanielk1977 set ::bomstr "\xFE\xFF" 206b5402fbfSdanielk1977 } 207b5402fbfSdanielk1977 append ::bomstr [encoding convertto unicode "123456789_123456789_12345678"] 208c08d405dSdanielk1977 } -tclbody { 209b5402fbfSdanielk1977 sqlite3_column_text16 $::STMT 0 210b5402fbfSdanielk1977 sqlite3_column_int $::STMT 0 211b5402fbfSdanielk1977 sqlite3_column_text16 $::STMT 1 212b5402fbfSdanielk1977 sqlite3_column_double $::STMT 1 213b5402fbfSdanielk1977 sqlite3_reset $::STMT 214b5402fbfSdanielk1977 sqlite3_bind_text16 $::STMT 1 $::bomstr 60 215c08d405dSdanielk1977 catch {sqlite3_finalize $::STMT} 216c08d405dSdanielk1977 if {[lindex [sqlite_malloc_stat] 2]<=0} { 217c08d405dSdanielk1977 error "out of memory" 218c08d405dSdanielk1977 } 219c08d405dSdanielk1977 } -cleanup { 220b5402fbfSdanielk1977 sqlite3_finalize $::STMT 221b5402fbfSdanielk1977 } 222b5402fbfSdanielk1977} 223b5402fbfSdanielk1977 2248b60e0f1Sdanielk1977# This block tests that malloc() failures that occur whilst commiting 2258b60e0f1Sdanielk1977# a multi-file transaction are handled correctly. 2268b60e0f1Sdanielk1977# 2274397de57Sdanielk1977do_malloc_test 9 -sqlprep { 2288b60e0f1Sdanielk1977 ATTACH 'test2.db' as test2; 2298b60e0f1Sdanielk1977 CREATE TABLE abc1(a, b, c); 2308b60e0f1Sdanielk1977 CREATE TABLE test2.abc2(a, b, c); 2314397de57Sdanielk1977} -sqlbody { 2328b60e0f1Sdanielk1977 BEGIN; 2338b60e0f1Sdanielk1977 INSERT INTO abc1 VALUES(1, 2, 3); 2348b60e0f1Sdanielk1977 INSERT INTO abc2 VALUES(1, 2, 3); 2358b60e0f1Sdanielk1977 COMMIT; 2368b60e0f1Sdanielk1977} 2378b60e0f1Sdanielk1977 2384397de57Sdanielk1977# This block tests malloc() failures that occur while opening a 2394397de57Sdanielk1977# connection to a database. 2404397de57Sdanielk1977do_malloc_test 10 -sqlprep { 2414397de57Sdanielk1977 CREATE TABLE abc(a, b, c); 2424397de57Sdanielk1977} -tclbody { 243c5859718Sdanielk1977 db close 244771151b6Sdanielk1977 sqlite3 db2 test.db 2454397de57Sdanielk1977 db2 eval {SELECT * FROM sqlite_master} 2464397de57Sdanielk1977 db2 close 2474397de57Sdanielk1977} 2484397de57Sdanielk1977 2494397de57Sdanielk1977# This block tests malloc() failures that occur within calls to 2504397de57Sdanielk1977# sqlite3_create_function(). 2514397de57Sdanielk1977do_malloc_test 11 -tclbody { 2522c336549Sdanielk1977 set rc [sqlite3_create_function $::DB] 2532c336549Sdanielk1977 if {[string match $rc SQLITE_NOMEM]} { 2544397de57Sdanielk1977 error "out of memory" 2554397de57Sdanielk1977 } 2564397de57Sdanielk1977} 2574397de57Sdanielk1977 2584397de57Sdanielk1977do_malloc_test 12 -tclbody { 2594397de57Sdanielk1977 set sql16 [encoding convertto unicode "SELECT * FROM sqlite_master"] 2604397de57Sdanielk1977 append sql16 "\00\00" 2614397de57Sdanielk1977 set ::STMT [sqlite3_prepare16 $::DB $sql16 -1 DUMMY] 2624397de57Sdanielk1977 sqlite3_finalize $::STMT 2634397de57Sdanielk1977} 2648b60e0f1Sdanielk1977 265aca790acSdanielk1977# Test malloc errors when replaying two hot journals from a 2-file 26666560adaSdrh# transaction. 26766560adaSdrhifcapable crashtest { 268aca790acSdanielk1977 do_malloc_test 13 -tclprep { 26959a33f98Sdanielk1977 set rc [crashsql -delay 1 -file test2.db { 270aca790acSdanielk1977 ATTACH 'test2.db' as aux; 271aca790acSdanielk1977 PRAGMA cache_size = 10; 272aca790acSdanielk1977 BEGIN; 273aca790acSdanielk1977 CREATE TABLE aux.t2(a, b, c); 274aca790acSdanielk1977 CREATE TABLE t1(a, b, c); 275aca790acSdanielk1977 COMMIT; 276aca790acSdanielk1977 }] 277aca790acSdanielk1977 if {$rc!="1 {child process exited abnormally}"} { 278aca790acSdanielk1977 error "Wrong error message: $rc" 279aca790acSdanielk1977 } 280950f054cSdanielk1977 } -tclbody { 281950f054cSdanielk1977 db eval {ATTACH 'test2.db' as aux;} 282950f054cSdanielk1977 set rc [catch {db eval { 283aca790acSdanielk1977 SELECT * FROM t1; 284aca790acSdanielk1977 SELECT * FROM t2; 285950f054cSdanielk1977 }} err] 286950f054cSdanielk1977 if {$rc && $err!="no such table: t1"} { 287950f054cSdanielk1977 error $err 288950f054cSdanielk1977 } 289aca790acSdanielk1977 } 290aca790acSdanielk1977} 291aca790acSdanielk1977 29276b047d9Sdanielk1977if {$tcl_platform(platform)!="windows"} { 293aca790acSdanielk1977 do_malloc_test 14 -tclprep { 294aca790acSdanielk1977 catch {db close} 295aca790acSdanielk1977 sqlite3 db2 test2.db 296aca790acSdanielk1977 db2 eval { 297aca790acSdanielk1977 PRAGMA synchronous = 0; 298aca790acSdanielk1977 CREATE TABLE t1(a, b); 299aca790acSdanielk1977 INSERT INTO t1 VALUES(1, 2); 300aca790acSdanielk1977 BEGIN; 301aca790acSdanielk1977 INSERT INTO t1 VALUES(3, 4); 302aca790acSdanielk1977 } 30332554c10Sdanielk1977 copy_file test2.db test.db 30432554c10Sdanielk1977 copy_file test2.db-journal test.db-journal 305aca790acSdanielk1977 db2 close 306aca790acSdanielk1977 } -tclbody { 307aca790acSdanielk1977 sqlite3 db test.db 308aca790acSdanielk1977 db eval { 309aca790acSdanielk1977 SELECT * FROM t1; 310aca790acSdanielk1977 } 311aca790acSdanielk1977 } 31276b047d9Sdanielk1977} 313aca790acSdanielk1977 3149a30cf65Sdanielk1977proc string_compare {a b} { 3159a30cf65Sdanielk1977 return [string compare $a $b] 3169a30cf65Sdanielk1977} 3179a30cf65Sdanielk1977 3189a30cf65Sdanielk1977# Test for malloc() failures in sqlite3_create_collation() and 3199a30cf65Sdanielk1977# sqlite3_create_collation16(). 320950f054cSdanielk1977# 3219a30cf65Sdanielk1977do_malloc_test 15 -tclbody { 3229a30cf65Sdanielk1977 db collate string_compare string_compare 3239a30cf65Sdanielk1977 if {[catch {add_test_collate $::DB 1 1 1} msg]} { 3249a30cf65Sdanielk1977 if {$msg=="SQLITE_NOMEM"} {set msg "out of memory"} 3259a30cf65Sdanielk1977 error $msg 3269a30cf65Sdanielk1977 } 327950f054cSdanielk1977 328950f054cSdanielk1977 db complete {SELECT "hello """||'world"' [microsoft], * FROM anicetable;} 329950f054cSdanielk1977 db complete {-- Useful comment} 330950f054cSdanielk1977 3319a30cf65Sdanielk1977 execsql { 3329a30cf65Sdanielk1977 CREATE TABLE t1(a, b COLLATE string_compare); 3339a30cf65Sdanielk1977 INSERT INTO t1 VALUES(10, 'string'); 3349a30cf65Sdanielk1977 INSERT INTO t1 VALUES(10, 'string2'); 3359a30cf65Sdanielk1977 } 3369a30cf65Sdanielk1977} 3379a30cf65Sdanielk1977 338950f054cSdanielk1977# Also test sqlite3_complete(). There are (currently) no malloc() 339950f054cSdanielk1977# calls in this function, but test anyway against future changes. 340950f054cSdanielk1977# 341950f054cSdanielk1977do_malloc_test 16 -tclbody { 342950f054cSdanielk1977 db complete {SELECT "hello """||'world"' [microsoft], * FROM anicetable;} 343950f054cSdanielk1977 db complete {-- Useful comment} 344950f054cSdanielk1977 db eval { 345950f054cSdanielk1977 SELECT * FROM sqlite_master; 346950f054cSdanielk1977 } 347950f054cSdanielk1977} 348950f054cSdanielk1977 349950f054cSdanielk1977# Test handling of malloc() failures in sqlite3_open16(). 350950f054cSdanielk1977# 351950f054cSdanielk1977do_malloc_test 17 -tclbody { 352950f054cSdanielk1977 set DB2 0 353950f054cSdanielk1977 set STMT 0 354950f054cSdanielk1977 355950f054cSdanielk1977 # open database using sqlite3_open16() 356d9910fe5Sdrh set filename [encoding convertto unicode test.db] 357d9910fe5Sdrh append filename "\x00\x00" 358d9910fe5Sdrh set DB2 [sqlite3_open16 $filename -unused] 359950f054cSdanielk1977 if {0==$DB2} { 360950f054cSdanielk1977 error "out of memory" 361950f054cSdanielk1977 } 362950f054cSdanielk1977 363950f054cSdanielk1977 # Prepare statement 364950f054cSdanielk1977 set rc [catch {sqlite3_prepare $DB2 {SELECT * FROM sqlite_master} -1 X} msg] 365950f054cSdanielk1977 if {$rc} { 366950f054cSdanielk1977 error [string range $msg 4 end] 367950f054cSdanielk1977 } 368950f054cSdanielk1977 set STMT $msg 369950f054cSdanielk1977 370950f054cSdanielk1977 # Finalize statement 371950f054cSdanielk1977 set rc [sqlite3_finalize $STMT] 372950f054cSdanielk1977 if {$rc!="SQLITE_OK"} { 373950f054cSdanielk1977 error [sqlite3_errmsg $DB2] 374950f054cSdanielk1977 } 375950f054cSdanielk1977 set STMT 0 376950f054cSdanielk1977 377950f054cSdanielk1977 # Close database 378950f054cSdanielk1977 set rc [sqlite3_close $DB2] 379950f054cSdanielk1977 if {$rc!="SQLITE_OK"} { 380950f054cSdanielk1977 error [sqlite3_errmsg $DB2] 381950f054cSdanielk1977 } 382950f054cSdanielk1977 set DB2 0 383950f054cSdanielk1977} -cleanup { 384950f054cSdanielk1977 if {$STMT!="0"} { 385950f054cSdanielk1977 sqlite3_finalize $STMT 386950f054cSdanielk1977 } 387950f054cSdanielk1977 if {$DB2!="0"} { 388950f054cSdanielk1977 set rc [sqlite3_close $DB2] 389950f054cSdanielk1977 } 390950f054cSdanielk1977} 391950f054cSdanielk1977 392950f054cSdanielk1977# Test handling of malloc() failures in sqlite3_errmsg16(). 393950f054cSdanielk1977# 394950f054cSdanielk1977do_malloc_test 18 -tclbody { 395950f054cSdanielk1977 catch { 396950f054cSdanielk1977 db eval "SELECT [string repeat longcolumnname 10] FROM sqlite_master" 397950f054cSdanielk1977 } msg 398950f054cSdanielk1977 if {$msg=="out of memory"} {error $msg} 399950f054cSdanielk1977 set utf16 [sqlite3_errmsg16 [sqlite3_connection_pointer db]] 400950f054cSdanielk1977 binary scan $utf16 c* bytes 401950f054cSdanielk1977 if {[llength $bytes]==0} { 402950f054cSdanielk1977 error "out of memory" 403950f054cSdanielk1977 } 404950f054cSdanielk1977} 405950f054cSdanielk1977 406161fb796Sdanielk1977# This test is aimed at coverage testing. Specificly, it is supposed to 407161fb796Sdanielk1977# cause a malloc() only used when converting between the two utf-16 408161fb796Sdanielk1977# encodings to fail (i.e. little-endian->big-endian). It only actually 409161fb796Sdanielk1977# hits this malloc() on little-endian hosts. 410161fb796Sdanielk1977# 411161fb796Sdanielk1977set static_string "\x00h\x00e\x00l\x00l\x00o" 412161fb796Sdanielk1977for {set l 0} {$l<10} {incr l} { 413161fb796Sdanielk1977 append static_string $static_string 414161fb796Sdanielk1977} 415161fb796Sdanielk1977append static_string "\x00\x00" 416161fb796Sdanielk1977do_malloc_test 19 -tclprep { 417161fb796Sdanielk1977 execsql { 418161fb796Sdanielk1977 PRAGMA encoding = "UTF16be"; 419161fb796Sdanielk1977 CREATE TABLE abc(a, b, c); 420161fb796Sdanielk1977 } 421161fb796Sdanielk1977} -tclbody { 422161fb796Sdanielk1977 unset -nocomplain ::STMT 423161fb796Sdanielk1977 set r [catch { 424161fb796Sdanielk1977 set ::STMT [sqlite3_prepare $::DB {SELECT ?} -1 DUMMY] 425161fb796Sdanielk1977 sqlite3_bind_text16 -static $::STMT 1 $static_string 112 426161fb796Sdanielk1977 } msg] 427161fb796Sdanielk1977 if {$r} {error [string range $msg 4 end]} 428161fb796Sdanielk1977 set msg 429161fb796Sdanielk1977} -cleanup { 430161fb796Sdanielk1977 if {[info exists ::STMT]} { 431161fb796Sdanielk1977 sqlite3_finalize $::STMT 432161fb796Sdanielk1977 } 433161fb796Sdanielk1977} 434161fb796Sdanielk1977unset static_string 435161fb796Sdanielk1977 4366103fe97Sdrh# Make sure SQLITE_NOMEM is reported out on an ATTACH failure even 4376103fe97Sdrh# when the malloc failure occurs within the nested parse. 4386103fe97Sdrh# 4396103fe97Sdrhdo_malloc_test 20 -tclprep { 4406103fe97Sdrh db close 4416103fe97Sdrh file delete -force test2.db test2.db-journal 4426103fe97Sdrh sqlite3 db test2.db 4436103fe97Sdrh db eval {CREATE TABLE t1(x);} 4446103fe97Sdrh db close 4456103fe97Sdrh} -tclbody { 4466103fe97Sdrh if {[catch {sqlite3 db test.db}]} { 4476103fe97Sdrh error "out of memory" 4486103fe97Sdrh } 4496103fe97Sdrh} -sqlbody { 4506103fe97Sdrh ATTACH DATABASE 'test2.db' AS t2; 4516103fe97Sdrh SELECT * FROM t1; 4526103fe97Sdrh DETACH DATABASE t2; 4536103fe97Sdrh} 4546103fe97Sdrh 455b5584c0cSdanielk1977# Test malloc failure whilst installing a foreign key. 45669b637b5Sdanielk1977# 45769b637b5Sdanielk1977do_malloc_test 21 -sqlbody { 45869b637b5Sdanielk1977 CREATE TABLE abc(a, b, c, FOREIGN KEY(a) REFERENCES abc(b)) 45969b637b5Sdanielk1977} 46069b637b5Sdanielk1977 4617e29e956Sdanielk1977# Test malloc failure in an sqlite3_prepare_v2() call. 4627e29e956Sdanielk1977# 4637e29e956Sdanielk1977do_malloc_test 22 -tclbody { 4647e29e956Sdanielk1977 set ::STMT "" 4657e29e956Sdanielk1977 set r [catch { 4667e29e956Sdanielk1977 set ::STMT [ 4677e29e956Sdanielk1977 sqlite3_prepare_v2 $::DB "SELECT * FROM sqlite_master" -1 DUMMY 4687e29e956Sdanielk1977 ] 4697e29e956Sdanielk1977 } msg] 4707e29e956Sdanielk1977 if {$r} {error [string range $msg 4 end]} 4717e29e956Sdanielk1977} -cleanup { 4727e29e956Sdanielk1977 if {$::STMT ne ""} { 4737e29e956Sdanielk1977 sqlite3_finalize $::STMT 4747e29e956Sdanielk1977 set ::STMT "" 4757e29e956Sdanielk1977 } 4767e29e956Sdanielk1977} 4777e29e956Sdanielk1977 47896fb0dd5Sdanielk1977# Ensure that no file descriptors were leaked. 479b5402fbfSdanielk1977do_test malloc-99.X { 48096fb0dd5Sdanielk1977 catch {db close} 48196fb0dd5Sdanielk1977 set sqlite_open_file_count 48296fb0dd5Sdanielk1977} {0} 48396fb0dd5Sdanielk1977 484344a6276Sdrhputs open-file-count=$sqlite_open_file_count 485ed7c855cSdrhsqlite_malloc_fail 0 486ed7c855cSdrhfinish_test 487