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# 12f3a65f7eSdrh# This file attempts to check the behavior of the SQLite library in 13f3a65f7eSdrh# an out-of-memory situation. When compiled with -DSQLITE_DEBUG=1, 14f3a65f7eSdrh# the SQLite library accepts a special command (sqlite3_memdebug_fail N C) 15f3a65f7eSdrh# which causes the N-th malloc to fail. This special feature is used 16f3a65f7eSdrh# to see what happens in the library if a malloc were to really fail 17f3a65f7eSdrh# due to an out-of-memory situation. 18f3a65f7eSdrh# 19*fa18beceSdanielk1977# $Id: malloc.test,v 1.46 2007/09/03 11:04:22 danielk1977 Exp $ 20ed7c855cSdrh 21ed7c855cSdrhset testdir [file dirname $argv0] 22ed7c855cSdrhsource $testdir/tester.tcl 23ed7c855cSdrh 24ed7c855cSdrh# Only run these tests if memory debugging is turned on. 25ed7c855cSdrh# 26f3a65f7eSdrhifcapable !memdebug { 27261919ccSdanielk1977 puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..." 28ed7c855cSdrh finish_test 29ed7c855cSdrh return 30ed7c855cSdrh} 31ed7c855cSdrh 32c9cf901dSdanielk1977source $testdir/malloc_common.tcl 334397de57Sdanielk1977 34c08d405dSdanielk1977do_malloc_test 1 -tclprep { 35c08d405dSdanielk1977 db close 36c08d405dSdanielk1977} -tclbody { 37c08d405dSdanielk1977 if {[catch {sqlite3 db test.db}]} { 38c08d405dSdanielk1977 error "out of memory" 39c08d405dSdanielk1977 } 40c08d405dSdanielk1977} -sqlbody { 41344a6276Sdrh DROP TABLE IF EXISTS t1; 42ed7c855cSdrh CREATE TABLE t1( 43ed7c855cSdrh a int, b float, c double, d text, e varchar(20), 44ed7c855cSdrh primary key(a,b,c) 45ed7c855cSdrh ); 46ed7c855cSdrh CREATE INDEX i1 ON t1(a,b); 4776f80796Sdrh INSERT INTO t1 VALUES(1,2.3,4.5,'hi',x'746865726500'); 48ed7c855cSdrh INSERT INTO t1 VALUES(6,7.0,0.8,'hello','out yonder'); 49ed7c855cSdrh SELECT * FROM t1; 50d400728aSdrh SELECT avg(b) FROM t1 GROUP BY a HAVING b>20.0; 516d4abfbeSdrh DELETE FROM t1 WHERE a IN (SELECT min(a) FROM t1); 52ed7c855cSdrh SELECT count(*) FROM t1; 53ed7c855cSdrh} 54d400728aSdrh 55b5548a8bSdanielk1977# Ensure that no file descriptors were leaked. 56b5548a8bSdanielk1977do_test malloc-1.X { 57b5548a8bSdanielk1977 catch {db close} 58b5548a8bSdanielk1977 set sqlite_open_file_count 59b5548a8bSdanielk1977} {0} 60b5548a8bSdanielk1977 61c08d405dSdanielk1977do_malloc_test 2 -sqlbody { 62fc23314aSdrh CREATE TABLE t1(a int, b int default 'abc', c int default 1); 63d400728aSdrh CREATE INDEX i1 ON t1(a,b); 645f3b4ab5Sdrh INSERT INTO t1 VALUES(1,1,'99 abcdefghijklmnopqrstuvwxyz'); 655f3b4ab5Sdrh INSERT INTO t1 VALUES(2,4,'98 abcdefghijklmnopqrstuvwxyz'); 665f3b4ab5Sdrh INSERT INTO t1 VALUES(3,9,'97 abcdefghijklmnopqrstuvwxyz'); 675f3b4ab5Sdrh INSERT INTO t1 VALUES(4,16,'96 abcdefghijklmnopqrstuvwxyz'); 685f3b4ab5Sdrh INSERT INTO t1 VALUES(5,25,'95 abcdefghijklmnopqrstuvwxyz'); 695f3b4ab5Sdrh INSERT INTO t1 VALUES(6,36,'94 abcdefghijklmnopqrstuvwxyz'); 706d4abfbeSdrh SELECT 'stuff', count(*) as 'other stuff', max(a+10) FROM t1; 716d4abfbeSdrh UPDATE t1 SET b=b||b||b||b; 72d400728aSdrh UPDATE t1 SET b=a WHERE a in (10,12,22); 736d4abfbeSdrh INSERT INTO t1(c,b,a) VALUES(20,10,5); 746d4abfbeSdrh INSERT INTO t1 SELECT * FROM t1 756d4abfbeSdrh WHERE a IN (SELECT a FROM t1 WHERE a<10); 766d4abfbeSdrh DELETE FROM t1 WHERE a>=10; 77d400728aSdrh DROP INDEX i1; 786d4abfbeSdrh DELETE FROM t1; 796d4abfbeSdrh} 806d4abfbeSdrh 81b5548a8bSdanielk1977# Ensure that no file descriptors were leaked. 82b5548a8bSdanielk1977do_test malloc-2.X { 83b5548a8bSdanielk1977 catch {db close} 84b5548a8bSdanielk1977 set sqlite_open_file_count 85b5548a8bSdanielk1977} {0} 86b5548a8bSdanielk1977 87c08d405dSdanielk1977do_malloc_test 3 -sqlbody { 886d4abfbeSdrh BEGIN TRANSACTION; 896d4abfbeSdrh CREATE TABLE t1(a int, b int, c int); 906d4abfbeSdrh CREATE INDEX i1 ON t1(a,b); 915f3b4ab5Sdrh INSERT INTO t1 VALUES(1,1,99); 925f3b4ab5Sdrh INSERT INTO t1 VALUES(2,4,98); 935f3b4ab5Sdrh INSERT INTO t1 VALUES(3,9,97); 945f3b4ab5Sdrh INSERT INTO t1 VALUES(4,16,96); 955f3b4ab5Sdrh INSERT INTO t1 VALUES(5,25,95); 965f3b4ab5Sdrh INSERT INTO t1 VALUES(6,36,94); 976d4abfbeSdrh INSERT INTO t1(c,b,a) VALUES(20,10,5); 986d4abfbeSdrh DELETE FROM t1 WHERE a>=10; 996d4abfbeSdrh DROP INDEX i1; 1006d4abfbeSdrh DELETE FROM t1; 1016d4abfbeSdrh ROLLBACK; 1026d4abfbeSdrh} 103c08d405dSdanielk1977 104b5548a8bSdanielk1977 105b5548a8bSdanielk1977# Ensure that no file descriptors were leaked. 106b5548a8bSdanielk1977do_test malloc-3.X { 107b5548a8bSdanielk1977 catch {db close} 108b5548a8bSdanielk1977 set sqlite_open_file_count 109b5548a8bSdanielk1977} {0} 110b5548a8bSdanielk1977 111c08d405dSdanielk1977do_malloc_test 4 -sqlbody { 1126d4abfbeSdrh BEGIN TRANSACTION; 1136d4abfbeSdrh CREATE TABLE t1(a int, b int, c int); 1146d4abfbeSdrh CREATE INDEX i1 ON t1(a,b); 1155f3b4ab5Sdrh INSERT INTO t1 VALUES(1,1,99); 1165f3b4ab5Sdrh INSERT INTO t1 VALUES(2,4,98); 1175f3b4ab5Sdrh INSERT INTO t1 VALUES(3,9,97); 1185f3b4ab5Sdrh INSERT INTO t1 VALUES(4,16,96); 1195f3b4ab5Sdrh INSERT INTO t1 VALUES(5,25,95); 1205f3b4ab5Sdrh INSERT INTO t1 VALUES(6,36,94); 1216d4abfbeSdrh UPDATE t1 SET b=a WHERE a in (10,12,22); 1226d4abfbeSdrh INSERT INTO t1 SELECT * FROM t1 1236d4abfbeSdrh WHERE a IN (SELECT a FROM t1 WHERE a<10); 1246d4abfbeSdrh DROP INDEX i1; 1256d4abfbeSdrh DELETE FROM t1; 1266d4abfbeSdrh COMMIT; 127d400728aSdrh} 128b5548a8bSdanielk1977 129b5548a8bSdanielk1977# Ensure that no file descriptors were leaked. 130b5548a8bSdanielk1977do_test malloc-4.X { 131b5548a8bSdanielk1977 catch {db close} 132b5548a8bSdanielk1977 set sqlite_open_file_count 133b5548a8bSdanielk1977} {0} 134b5548a8bSdanielk1977 135c08d405dSdanielk1977do_malloc_test 5 -sqlbody { 136e4697f5eSdrh BEGIN TRANSACTION; 137e4697f5eSdrh CREATE TABLE t1(a,b); 138e4697f5eSdrh CREATE TABLE t2(x,y); 139e4697f5eSdrh CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN 140e4697f5eSdrh INSERT INTO t2(x,y) VALUES(new.rowid,1); 1419fb3ecbcSdanielk1977 INSERT INTO t2(x,y) SELECT * FROM t2; 1429fb3ecbcSdanielk1977 INSERT INTO t2 SELECT * FROM t2; 14328f45914Sdrh UPDATE t2 SET y=y+1 WHERE x=new.rowid; 14428f45914Sdrh SELECT 123; 14528f45914Sdrh DELETE FROM t2 WHERE x=new.rowid; 146e4697f5eSdrh END; 147e4697f5eSdrh INSERT INTO t1(a,b) VALUES(2,3); 148e4697f5eSdrh COMMIT; 149e4697f5eSdrh} 150b5548a8bSdanielk1977 151b5548a8bSdanielk1977# Ensure that no file descriptors were leaked. 152b5548a8bSdanielk1977do_test malloc-5.X { 153b5548a8bSdanielk1977 catch {db close} 154b5548a8bSdanielk1977 set sqlite_open_file_count 155b5548a8bSdanielk1977} {0} 156b5548a8bSdanielk1977 157c08d405dSdanielk1977do_malloc_test 6 -sqlprep { 15896fb0dd5Sdanielk1977 BEGIN TRANSACTION; 15996fb0dd5Sdanielk1977 CREATE TABLE t1(a); 16096fb0dd5Sdanielk1977 INSERT INTO t1 VALUES(1); 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 INSERT INTO t1 SELECT a*2 FROM t1; 16896fb0dd5Sdanielk1977 INSERT INTO t1 SELECT a*2 FROM t1; 16996fb0dd5Sdanielk1977 INSERT INTO t1 SELECT a*2 FROM t1; 17096fb0dd5Sdanielk1977 INSERT INTO t1 SELECT a*2 FROM t1; 17196fb0dd5Sdanielk1977 DELETE FROM t1 where rowid%5 = 0; 17296fb0dd5Sdanielk1977 COMMIT; 173c08d405dSdanielk1977} -sqlbody { 17496fb0dd5Sdanielk1977 VACUUM; 17596fb0dd5Sdanielk1977} 17696fb0dd5Sdanielk1977 177c08d405dSdanielk1977do_malloc_test 7 -sqlprep { 17801427a62Sdanielk1977 CREATE TABLE t1(a, b); 17901427a62Sdanielk1977 INSERT INTO t1 VALUES(1, 2); 18001427a62Sdanielk1977 INSERT INTO t1 VALUES(3, 4); 18101427a62Sdanielk1977 INSERT INTO t1 VALUES(5, 6); 182b5402fbfSdanielk1977 INSERT INTO t1 VALUES(7, randstr(1200,1200)); 183c08d405dSdanielk1977} -sqlbody { 184b5402fbfSdanielk1977 SELECT min(a) FROM t1 WHERE a<6 GROUP BY b; 185b5402fbfSdanielk1977 SELECT a FROM t1 WHERE a<6 ORDER BY a; 186b5402fbfSdanielk1977 SELECT b FROM t1 WHERE a>6; 18701427a62Sdanielk1977} 18801427a62Sdanielk1977 189b5402fbfSdanielk1977# This block is designed to test that some malloc failures that may 190b5402fbfSdanielk1977# occur in vdbeapi.c. Specifically, if a malloc failure that occurs 191b5402fbfSdanielk1977# when converting UTF-16 text to integers and real numbers is handled 192b5402fbfSdanielk1977# correctly. 193b5402fbfSdanielk1977# 1948b60e0f1Sdanielk1977# This is done by retrieving a string from the database engine and 1958b60e0f1Sdanielk1977# manipulating it using the sqlite3_column_*** APIs. This doesn't 1968b60e0f1Sdanielk1977# actually return an error to the user when a malloc() fails.. That 1978b60e0f1Sdanielk1977# could be viewed as a bug. 1988b60e0f1Sdanielk1977# 1998b60e0f1Sdanielk1977# These tests only run if UTF-16 support is compiled in. 200b5402fbfSdanielk1977# 201c08d405dSdanielk1977if {$::sqlite_options(utf16)} { 202f3a65f7eSdrh set ::STMT {} 203c08d405dSdanielk1977 do_malloc_test 8 -tclprep { 204b5402fbfSdanielk1977 set sql "SELECT '[string repeat abc 20]', '[string repeat def 20]', ?" 205f3a65f7eSdrh set ::STMT [sqlite3_prepare db $sql -1 X] 206b5402fbfSdanielk1977 sqlite3_step $::STMT 207b5402fbfSdanielk1977 if { $::tcl_platform(byteOrder)=="littleEndian" } { 208b5402fbfSdanielk1977 set ::bomstr "\xFF\xFE" 209b5402fbfSdanielk1977 } else { 210b5402fbfSdanielk1977 set ::bomstr "\xFE\xFF" 211b5402fbfSdanielk1977 } 212b5402fbfSdanielk1977 append ::bomstr [encoding convertto unicode "123456789_123456789_12345678"] 213c08d405dSdanielk1977 } -tclbody { 214b5402fbfSdanielk1977 sqlite3_column_text16 $::STMT 0 215b5402fbfSdanielk1977 sqlite3_column_int $::STMT 0 216b5402fbfSdanielk1977 sqlite3_column_text16 $::STMT 1 217b5402fbfSdanielk1977 sqlite3_column_double $::STMT 1 218a1644fd8Sdanielk1977 set rc [sqlite3_reset $::STMT] 219a1644fd8Sdanielk1977 if {$rc eq "SQLITE_NOMEM"} {error "out of memory"} 220b5402fbfSdanielk1977 sqlite3_bind_text16 $::STMT 1 $::bomstr 60 221f3a65f7eSdrh #catch {sqlite3_finalize $::STMT} 222f3a65f7eSdrh #if {[lindex [sqlite_malloc_stat] 2]<=0} { 223f3a65f7eSdrh # error "out of memory" 224f3a65f7eSdrh #} 225c08d405dSdanielk1977 } -cleanup { 226f3a65f7eSdrh if {$::STMT!=""} { 227b5402fbfSdanielk1977 sqlite3_finalize $::STMT 228f3a65f7eSdrh set ::STMT {} 229f3a65f7eSdrh } 230b5402fbfSdanielk1977 } 231b5402fbfSdanielk1977} 232b5402fbfSdanielk1977 2338b60e0f1Sdanielk1977# This block tests that malloc() failures that occur whilst commiting 2348b60e0f1Sdanielk1977# a multi-file transaction are handled correctly. 2358b60e0f1Sdanielk1977# 2364397de57Sdanielk1977do_malloc_test 9 -sqlprep { 2378b60e0f1Sdanielk1977 ATTACH 'test2.db' as test2; 2388b60e0f1Sdanielk1977 CREATE TABLE abc1(a, b, c); 2398b60e0f1Sdanielk1977 CREATE TABLE test2.abc2(a, b, c); 2404397de57Sdanielk1977} -sqlbody { 2418b60e0f1Sdanielk1977 BEGIN; 2428b60e0f1Sdanielk1977 INSERT INTO abc1 VALUES(1, 2, 3); 2438b60e0f1Sdanielk1977 INSERT INTO abc2 VALUES(1, 2, 3); 2448b60e0f1Sdanielk1977 COMMIT; 2458b60e0f1Sdanielk1977} 2468b60e0f1Sdanielk1977 2474397de57Sdanielk1977# This block tests malloc() failures that occur while opening a 2484397de57Sdanielk1977# connection to a database. 2494397de57Sdanielk1977do_malloc_test 10 -sqlprep { 2504397de57Sdanielk1977 CREATE TABLE abc(a, b, c); 2514397de57Sdanielk1977} -tclbody { 252c5859718Sdanielk1977 db close 253771151b6Sdanielk1977 sqlite3 db2 test.db 2544397de57Sdanielk1977 db2 eval {SELECT * FROM sqlite_master} 2554397de57Sdanielk1977 db2 close 2564397de57Sdanielk1977} 2574397de57Sdanielk1977 2584397de57Sdanielk1977# This block tests malloc() failures that occur within calls to 2594397de57Sdanielk1977# sqlite3_create_function(). 2604397de57Sdanielk1977do_malloc_test 11 -tclbody { 261f3a65f7eSdrh set rc [sqlite3_create_function db] 262*fa18beceSdanielk1977 if {[string match $rc SQLITE_OK]} { 263*fa18beceSdanielk1977 set rc [sqlite3_create_aggregate db] 264*fa18beceSdanielk1977 } 2652c336549Sdanielk1977 if {[string match $rc SQLITE_NOMEM]} { 2664397de57Sdanielk1977 error "out of memory" 2674397de57Sdanielk1977 } 2684397de57Sdanielk1977} 2694397de57Sdanielk1977 2704397de57Sdanielk1977do_malloc_test 12 -tclbody { 2714397de57Sdanielk1977 set sql16 [encoding convertto unicode "SELECT * FROM sqlite_master"] 2724397de57Sdanielk1977 append sql16 "\00\00" 273f3a65f7eSdrh set ::STMT [sqlite3_prepare16 db $sql16 -1 DUMMY] 2744397de57Sdanielk1977 sqlite3_finalize $::STMT 2754397de57Sdanielk1977} 2768b60e0f1Sdanielk1977 277aca790acSdanielk1977# Test malloc errors when replaying two hot journals from a 2-file 27866560adaSdrh# transaction. 27966560adaSdrhifcapable crashtest { 280aca790acSdanielk1977 do_malloc_test 13 -tclprep { 28159a33f98Sdanielk1977 set rc [crashsql -delay 1 -file test2.db { 282aca790acSdanielk1977 ATTACH 'test2.db' as aux; 283aca790acSdanielk1977 PRAGMA cache_size = 10; 284aca790acSdanielk1977 BEGIN; 285aca790acSdanielk1977 CREATE TABLE aux.t2(a, b, c); 286aca790acSdanielk1977 CREATE TABLE t1(a, b, c); 287aca790acSdanielk1977 COMMIT; 288aca790acSdanielk1977 }] 289aca790acSdanielk1977 if {$rc!="1 {child process exited abnormally}"} { 290aca790acSdanielk1977 error "Wrong error message: $rc" 291aca790acSdanielk1977 } 292950f054cSdanielk1977 } -tclbody { 293950f054cSdanielk1977 db eval {ATTACH 'test2.db' as aux;} 294950f054cSdanielk1977 set rc [catch {db eval { 295aca790acSdanielk1977 SELECT * FROM t1; 296aca790acSdanielk1977 SELECT * FROM t2; 297950f054cSdanielk1977 }} err] 298950f054cSdanielk1977 if {$rc && $err!="no such table: t1"} { 299950f054cSdanielk1977 error $err 300950f054cSdanielk1977 } 301aca790acSdanielk1977 } 302aca790acSdanielk1977} 303aca790acSdanielk1977 30476b047d9Sdanielk1977if {$tcl_platform(platform)!="windows"} { 305aca790acSdanielk1977 do_malloc_test 14 -tclprep { 306aca790acSdanielk1977 catch {db close} 307aca790acSdanielk1977 sqlite3 db2 test2.db 308aca790acSdanielk1977 db2 eval { 309aca790acSdanielk1977 PRAGMA synchronous = 0; 310aca790acSdanielk1977 CREATE TABLE t1(a, b); 311aca790acSdanielk1977 INSERT INTO t1 VALUES(1, 2); 312aca790acSdanielk1977 BEGIN; 313aca790acSdanielk1977 INSERT INTO t1 VALUES(3, 4); 314aca790acSdanielk1977 } 31532554c10Sdanielk1977 copy_file test2.db test.db 31632554c10Sdanielk1977 copy_file test2.db-journal test.db-journal 317aca790acSdanielk1977 db2 close 318aca790acSdanielk1977 } -tclbody { 319aca790acSdanielk1977 sqlite3 db test.db 320aca790acSdanielk1977 db eval { 321aca790acSdanielk1977 SELECT * FROM t1; 322aca790acSdanielk1977 } 323aca790acSdanielk1977 } 32476b047d9Sdanielk1977} 325aca790acSdanielk1977 3269a30cf65Sdanielk1977proc string_compare {a b} { 3279a30cf65Sdanielk1977 return [string compare $a $b] 3289a30cf65Sdanielk1977} 3299a30cf65Sdanielk1977 3309a30cf65Sdanielk1977# Test for malloc() failures in sqlite3_create_collation() and 3319a30cf65Sdanielk1977# sqlite3_create_collation16(). 332950f054cSdanielk1977# 333f3a65f7eSdrhdo_malloc_test 15 -start 4 -tclbody { 3349a30cf65Sdanielk1977 db collate string_compare string_compare 335f3a65f7eSdrh if {[catch {add_test_collate db 1 1 1} msg]} { 3369a30cf65Sdanielk1977 if {$msg=="SQLITE_NOMEM"} {set msg "out of memory"} 3379a30cf65Sdanielk1977 error $msg 3389a30cf65Sdanielk1977 } 339950f054cSdanielk1977 340950f054cSdanielk1977 db complete {SELECT "hello """||'world"' [microsoft], * FROM anicetable;} 341950f054cSdanielk1977 db complete {-- Useful comment} 342950f054cSdanielk1977 3439a30cf65Sdanielk1977 execsql { 3449a30cf65Sdanielk1977 CREATE TABLE t1(a, b COLLATE string_compare); 3459a30cf65Sdanielk1977 INSERT INTO t1 VALUES(10, 'string'); 3469a30cf65Sdanielk1977 INSERT INTO t1 VALUES(10, 'string2'); 3479a30cf65Sdanielk1977 } 3489a30cf65Sdanielk1977} 3499a30cf65Sdanielk1977 350950f054cSdanielk1977# Also test sqlite3_complete(). There are (currently) no malloc() 351950f054cSdanielk1977# calls in this function, but test anyway against future changes. 352950f054cSdanielk1977# 353950f054cSdanielk1977do_malloc_test 16 -tclbody { 354950f054cSdanielk1977 db complete {SELECT "hello """||'world"' [microsoft], * FROM anicetable;} 355950f054cSdanielk1977 db complete {-- Useful comment} 356950f054cSdanielk1977 db eval { 357950f054cSdanielk1977 SELECT * FROM sqlite_master; 358950f054cSdanielk1977 } 359950f054cSdanielk1977} 360950f054cSdanielk1977 361950f054cSdanielk1977# Test handling of malloc() failures in sqlite3_open16(). 362950f054cSdanielk1977# 363950f054cSdanielk1977do_malloc_test 17 -tclbody { 364950f054cSdanielk1977 set DB2 0 365950f054cSdanielk1977 set STMT 0 366950f054cSdanielk1977 367950f054cSdanielk1977 # open database using sqlite3_open16() 368d9910fe5Sdrh set filename [encoding convertto unicode test.db] 369d9910fe5Sdrh append filename "\x00\x00" 370d9910fe5Sdrh set DB2 [sqlite3_open16 $filename -unused] 371950f054cSdanielk1977 if {0==$DB2} { 372950f054cSdanielk1977 error "out of memory" 373950f054cSdanielk1977 } 374950f054cSdanielk1977 375950f054cSdanielk1977 # Prepare statement 376950f054cSdanielk1977 set rc [catch {sqlite3_prepare $DB2 {SELECT * FROM sqlite_master} -1 X} msg] 377950f054cSdanielk1977 if {$rc} { 378950f054cSdanielk1977 error [string range $msg 4 end] 379950f054cSdanielk1977 } 380950f054cSdanielk1977 set STMT $msg 381950f054cSdanielk1977 382950f054cSdanielk1977 # Finalize statement 383950f054cSdanielk1977 set rc [sqlite3_finalize $STMT] 384950f054cSdanielk1977 if {$rc!="SQLITE_OK"} { 385950f054cSdanielk1977 error [sqlite3_errmsg $DB2] 386950f054cSdanielk1977 } 387950f054cSdanielk1977 set STMT 0 388950f054cSdanielk1977 389950f054cSdanielk1977 # Close database 390950f054cSdanielk1977 set rc [sqlite3_close $DB2] 391950f054cSdanielk1977 if {$rc!="SQLITE_OK"} { 392950f054cSdanielk1977 error [sqlite3_errmsg $DB2] 393950f054cSdanielk1977 } 394950f054cSdanielk1977 set DB2 0 395950f054cSdanielk1977} -cleanup { 396950f054cSdanielk1977 if {$STMT!="0"} { 397950f054cSdanielk1977 sqlite3_finalize $STMT 398950f054cSdanielk1977 } 399950f054cSdanielk1977 if {$DB2!="0"} { 400950f054cSdanielk1977 set rc [sqlite3_close $DB2] 401950f054cSdanielk1977 } 402950f054cSdanielk1977} 403950f054cSdanielk1977 404950f054cSdanielk1977# Test handling of malloc() failures in sqlite3_errmsg16(). 405950f054cSdanielk1977# 406950f054cSdanielk1977do_malloc_test 18 -tclbody { 407950f054cSdanielk1977 catch { 408950f054cSdanielk1977 db eval "SELECT [string repeat longcolumnname 10] FROM sqlite_master" 409950f054cSdanielk1977 } msg 410950f054cSdanielk1977 if {$msg=="out of memory"} {error $msg} 411950f054cSdanielk1977 set utf16 [sqlite3_errmsg16 [sqlite3_connection_pointer db]] 412950f054cSdanielk1977 binary scan $utf16 c* bytes 413950f054cSdanielk1977 if {[llength $bytes]==0} { 414950f054cSdanielk1977 error "out of memory" 415950f054cSdanielk1977 } 416950f054cSdanielk1977} 417950f054cSdanielk1977 418161fb796Sdanielk1977# This test is aimed at coverage testing. Specificly, it is supposed to 419161fb796Sdanielk1977# cause a malloc() only used when converting between the two utf-16 420161fb796Sdanielk1977# encodings to fail (i.e. little-endian->big-endian). It only actually 421161fb796Sdanielk1977# hits this malloc() on little-endian hosts. 422161fb796Sdanielk1977# 423161fb796Sdanielk1977set static_string "\x00h\x00e\x00l\x00l\x00o" 424161fb796Sdanielk1977for {set l 0} {$l<10} {incr l} { 425161fb796Sdanielk1977 append static_string $static_string 426161fb796Sdanielk1977} 427161fb796Sdanielk1977append static_string "\x00\x00" 428161fb796Sdanielk1977do_malloc_test 19 -tclprep { 429161fb796Sdanielk1977 execsql { 430161fb796Sdanielk1977 PRAGMA encoding = "UTF16be"; 431161fb796Sdanielk1977 CREATE TABLE abc(a, b, c); 432161fb796Sdanielk1977 } 433161fb796Sdanielk1977} -tclbody { 434161fb796Sdanielk1977 unset -nocomplain ::STMT 435161fb796Sdanielk1977 set r [catch { 436f3a65f7eSdrh set ::STMT [sqlite3_prepare db {SELECT ?} -1 DUMMY] 437161fb796Sdanielk1977 sqlite3_bind_text16 -static $::STMT 1 $static_string 112 438161fb796Sdanielk1977 } msg] 439161fb796Sdanielk1977 if {$r} {error [string range $msg 4 end]} 440161fb796Sdanielk1977 set msg 441161fb796Sdanielk1977} -cleanup { 442161fb796Sdanielk1977 if {[info exists ::STMT]} { 443161fb796Sdanielk1977 sqlite3_finalize $::STMT 444161fb796Sdanielk1977 } 445161fb796Sdanielk1977} 446161fb796Sdanielk1977unset static_string 447161fb796Sdanielk1977 4486103fe97Sdrh# Make sure SQLITE_NOMEM is reported out on an ATTACH failure even 4496103fe97Sdrh# when the malloc failure occurs within the nested parse. 4506103fe97Sdrh# 4516103fe97Sdrhdo_malloc_test 20 -tclprep { 4526103fe97Sdrh db close 4536103fe97Sdrh file delete -force test2.db test2.db-journal 4546103fe97Sdrh sqlite3 db test2.db 4556103fe97Sdrh db eval {CREATE TABLE t1(x);} 4566103fe97Sdrh db close 4576103fe97Sdrh} -tclbody { 4586103fe97Sdrh if {[catch {sqlite3 db test.db}]} { 4596103fe97Sdrh error "out of memory" 4606103fe97Sdrh } 4616103fe97Sdrh} -sqlbody { 4626103fe97Sdrh ATTACH DATABASE 'test2.db' AS t2; 4636103fe97Sdrh SELECT * FROM t1; 4646103fe97Sdrh DETACH DATABASE t2; 4656103fe97Sdrh} 4666103fe97Sdrh 467b5584c0cSdanielk1977# Test malloc failure whilst installing a foreign key. 46869b637b5Sdanielk1977# 46969b637b5Sdanielk1977do_malloc_test 21 -sqlbody { 47069b637b5Sdanielk1977 CREATE TABLE abc(a, b, c, FOREIGN KEY(a) REFERENCES abc(b)) 47169b637b5Sdanielk1977} 47269b637b5Sdanielk1977 4737e29e956Sdanielk1977# Test malloc failure in an sqlite3_prepare_v2() call. 4747e29e956Sdanielk1977# 4757e29e956Sdanielk1977do_malloc_test 22 -tclbody { 4767e29e956Sdanielk1977 set ::STMT "" 4777e29e956Sdanielk1977 set r [catch { 4787e29e956Sdanielk1977 set ::STMT [ 479f3a65f7eSdrh sqlite3_prepare_v2 db "SELECT * FROM sqlite_master" -1 DUMMY 4807e29e956Sdanielk1977 ] 4817e29e956Sdanielk1977 } msg] 4827e29e956Sdanielk1977 if {$r} {error [string range $msg 4 end]} 4837e29e956Sdanielk1977} -cleanup { 4847e29e956Sdanielk1977 if {$::STMT ne ""} { 4857e29e956Sdanielk1977 sqlite3_finalize $::STMT 4867e29e956Sdanielk1977 set ::STMT "" 4877e29e956Sdanielk1977 } 4887e29e956Sdanielk1977} 4897e29e956Sdanielk1977 49096fb0dd5Sdanielk1977# Ensure that no file descriptors were leaked. 491b5402fbfSdanielk1977do_test malloc-99.X { 49296fb0dd5Sdanielk1977 catch {db close} 49396fb0dd5Sdanielk1977 set sqlite_open_file_count 49496fb0dd5Sdanielk1977} {0} 49596fb0dd5Sdanielk1977 496344a6276Sdrhputs open-file-count=$sqlite_open_file_count 497ed7c855cSdrhfinish_test 498