Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Handle malloc() failures that occur in open16() and errmsg16(). (CVS 2967) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
86eab9e53db8d7fecc789fe3d8cd8d7b |
User & Date: | danielk1977 2006-01-18 05:51:58.000 |
Context
2006-01-18
| ||
14:06 | Convert the unix driver to use a recusive mutex. Similar changes to the windows driver are pending. (CVS 2968) (check-in: 8830bbbac8 user: drh tags: trunk) | |
05:51 | Handle malloc() failures that occur in open16() and errmsg16(). (CVS 2967) (check-in: 86eab9e53d user: danielk1977 tags: trunk) | |
04:26 | Handle malloc() failures that occur inside create_collation() calls. (CVS 2966) (check-in: 95c5903f36 user: danielk1977 tags: trunk) | |
Changes
Changes to src/main.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** ** $Id: main.c,v 1.326 2006/01/18 05:51:58 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* ** The following constant value is used by the SQLITE_BIGENDIAN and |
︙ | ︙ | |||
723 724 725 726 727 728 729 730 731 732 733 734 735 736 | } z = sqlite3_value_text16(db->pErr); if( z==0 ){ sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode), SQLITE_UTF8, SQLITE_STATIC); z = sqlite3_value_text16(db->pErr); } return z; } #endif /* SQLITE_OMIT_UTF16 */ /* ** Return the most recent error code generated by an SQLite routine. If NULL is ** passed to this function, we assume a malloc() failed during sqlite3_open(). | > | 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 | } z = sqlite3_value_text16(db->pErr); if( z==0 ){ sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode), SQLITE_UTF8, SQLITE_STATIC); z = sqlite3_value_text16(db->pErr); } sqlite3MallocClearFailed(); return z; } #endif /* SQLITE_OMIT_UTF16 */ /* ** Return the most recent error code generated by an SQLite routine. If NULL is ** passed to this function, we assume a malloc() failed during sqlite3_open(). |
︙ | ︙ | |||
926 927 928 929 930 931 932 933 934 935 936 937 938 939 | pVal = sqlite3ValueNew(); sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC); zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8); if( zFilename8 ){ rc = openDatabase(zFilename8, ppDb); if( rc==SQLITE_OK && *ppDb ){ rc = sqlite3_exec(*ppDb, "PRAGMA encoding = 'UTF-16'", 0, 0, 0); } }else{ assert( sqlite3ThreadDataReadOnly()->mallocFailed ); sqlite3MallocClearFailed(); } sqlite3ValueFree(pVal); | > > > > | 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 | pVal = sqlite3ValueNew(); sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC); zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8); if( zFilename8 ){ rc = openDatabase(zFilename8, ppDb); if( rc==SQLITE_OK && *ppDb ){ rc = sqlite3_exec(*ppDb, "PRAGMA encoding = 'UTF-16'", 0, 0, 0); if( rc!=SQLITE_OK ){ sqlite3_close(*ppDb); *ppDb = 0; } } }else{ assert( sqlite3ThreadDataReadOnly()->mallocFailed ); sqlite3MallocClearFailed(); } sqlite3ValueFree(pVal); |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the printf() interface to SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the printf() interface to SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test1.c,v 1.195 2006/01/18 05:51:58 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
2045 2046 2047 2048 2049 2050 2051 | Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ #ifndef SQLITE_OMIT_UTF16 sqlite3 *db; const void *zErr; | | > | > | 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 | Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ #ifndef SQLITE_OMIT_UTF16 sqlite3 *db; const void *zErr; int bytes = 0; if( objc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " DB", 0); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; zErr = sqlite3_errmsg16(db); if( zErr ){ bytes = sqlite3utf16ByteLen(zErr, -1); } Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(zErr, bytes)); #endif /* SQLITE_OMIT_UTF16 */ return TCL_OK; } /* ** Usage: sqlite3_prepare DB sql bytes tailvar |
︙ | ︙ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 | || (pTo->magic!=VDBE_MAGIC_RUN && pTo->magic!=VDBE_MAGIC_HALT) ){ return SQLITE_MISUSE; } if( pFrom->nVar!=pTo->nVar ){ return SQLITE_ERROR; } for(i=0; rc==SQLITE_OK && i<pFrom->nVar; i++){ rc = sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]); } return rc; } /* ** Return the sqlite3* database handle to which the prepared statement given ** in the argument belongs. This is the same database handle that was | > > | 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 | || (pTo->magic!=VDBE_MAGIC_RUN && pTo->magic!=VDBE_MAGIC_HALT) ){ return SQLITE_MISUSE; } if( pFrom->nVar!=pTo->nVar ){ return SQLITE_ERROR; } for(i=0; rc==SQLITE_OK && i<pFrom->nVar; i++){ sqlite3MallocDisallow(); rc = sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]); sqlite3MallocAllow(); } return rc; } /* ** Return the sqlite3* database handle to which the prepared statement given ** in the argument belongs. This is the same database handle that was |
︙ | ︙ |
Changes to test/malloc.test.
︙ | ︙ | |||
10 11 12 13 14 15 16 | #*********************************************************************** # This file attempts to check the library in an out-of-memory situation. # When compiled with -DSQLITE_DEBUG=1, the SQLite library accepts a special # command (sqlite_malloc_fail N) which causes the N-th malloc to fail. This # special feature is used to see what happens in the library if a malloc # were to really fail due to an out-of-memory situation. # | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #*********************************************************************** # This file attempts to check the library in an out-of-memory situation. # When compiled with -DSQLITE_DEBUG=1, the SQLite library accepts a special # command (sqlite_malloc_fail N) which causes the N-th malloc to fail. This # special feature is used to see what happens in the library if a malloc # were to really fail due to an out-of-memory situation. # # $Id: malloc.test,v 1.29 2006/01/18 05:51:58 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Only run these tests if memory debugging is turned on. # if {[info command sqlite_malloc_stat]==""} { |
︙ | ︙ | |||
106 107 108 109 110 111 112 | set v2 [expr {$msg=="" || $msg=="out of memory"}] if {!$v2} {puts "\nError message returned: $msg"} lappend v $v2 } } {1 1} if {[info exists ::mallocopts(-cleanup)]} { | | | 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | set v2 [expr {$msg=="" || $msg=="out of memory"}] if {!$v2} {puts "\nError message returned: $msg"} lappend v $v2 } } {1 1} if {[info exists ::mallocopts(-cleanup)]} { catch [list uplevel #0 $::mallocopts(-cleanup)] msg } } unset ::mallocopts } do_malloc_test 1 -tclprep { db close |
︙ | ︙ | |||
355 356 357 358 359 360 361 | CREATE TABLE aux.t2(a, b, c); CREATE TABLE t1(a, b, c); COMMIT; }] if {$rc!="1 {child process exited abnormally}"} { error "Wrong error message: $rc" } | | | > | | > > > > | 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 | CREATE TABLE aux.t2(a, b, c); CREATE TABLE t1(a, b, c); COMMIT; }] if {$rc!="1 {child process exited abnormally}"} { error "Wrong error message: $rc" } } -tclbody { db eval {ATTACH 'test2.db' as aux;} set rc [catch {db eval { SELECT * FROM t1; SELECT * FROM t2; }} err] if {$rc && $err!="no such table: t1"} { error $err } } } if {$tcl_platform(platform)!="windows"} { do_malloc_test 14 -tclprep { catch {db close} sqlite3 db2 test2.db |
︙ | ︙ | |||
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 | proc string_compare {a b} { return [string compare $a $b] } # Test for malloc() failures in sqlite3_create_collation() and # sqlite3_create_collation16(). do_malloc_test 15 -tclbody { db collate string_compare string_compare if {[catch {add_test_collate $::DB 1 1 1} msg]} { if {$msg=="SQLITE_NOMEM"} {set msg "out of memory"} error $msg } execsql { CREATE TABLE t1(a, b COLLATE string_compare); INSERT INTO t1 VALUES(10, 'string'); INSERT INTO t1 VALUES(10, 'string2'); } } # Ensure that no file descriptors were leaked. do_test malloc-99.X { catch {db close} set sqlite_open_file_count } {0} sqlite_malloc_fail 0 finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 | proc string_compare {a b} { return [string compare $a $b] } # Test for malloc() failures in sqlite3_create_collation() and # sqlite3_create_collation16(). # do_malloc_test 15 -tclbody { db collate string_compare string_compare if {[catch {add_test_collate $::DB 1 1 1} msg]} { if {$msg=="SQLITE_NOMEM"} {set msg "out of memory"} error $msg } db complete {SELECT "hello """||'world"' [microsoft], * FROM anicetable;} db complete {-- Useful comment} execsql { CREATE TABLE t1(a, b COLLATE string_compare); INSERT INTO t1 VALUES(10, 'string'); INSERT INTO t1 VALUES(10, 'string2'); } } # Also test sqlite3_complete(). There are (currently) no malloc() # calls in this function, but test anyway against future changes. # do_malloc_test 16 -tclbody { db complete {SELECT "hello """||'world"' [microsoft], * FROM anicetable;} db complete {-- Useful comment} db eval { SELECT * FROM sqlite_master; } } # Test handling of malloc() failures in sqlite3_open16(). # do_malloc_test 17 -tclbody { set DB2 0 set STMT 0 # open database using sqlite3_open16() set DB2 [sqlite3_open16 test.db -unused] if {0==$DB2} { error "out of memory" } # Prepare statement set rc [catch {sqlite3_prepare $DB2 {SELECT * FROM sqlite_master} -1 X} msg] if {$rc} { error [string range $msg 4 end] } set STMT $msg # Finalize statement set rc [sqlite3_finalize $STMT] if {$rc!="SQLITE_OK"} { error [sqlite3_errmsg $DB2] } set STMT 0 # Close database set rc [sqlite3_close $DB2] if {$rc!="SQLITE_OK"} { error [sqlite3_errmsg $DB2] } set DB2 0 } -cleanup { if {$STMT!="0"} { sqlite3_finalize $STMT } if {$DB2!="0"} { set rc [sqlite3_close $DB2] } } # Test handling of malloc() failures in sqlite3_errmsg16(). # do_malloc_test 18 -tclbody { catch { db eval "SELECT [string repeat longcolumnname 10] FROM sqlite_master" } msg if {$msg=="out of memory"} {error $msg} set utf16 [sqlite3_errmsg16 [sqlite3_connection_pointer db]] binary scan $utf16 c* bytes if {[llength $bytes]==0} { error "out of memory" } } # Ensure that no file descriptors were leaked. do_test malloc-99.X { catch {db close} set sqlite_open_file_count } {0} sqlite_malloc_fail 0 finish_test |