Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add some tests for malloc() failure within the column_name() and column_decl() APIs. (CVS 2805) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
78f10ca0a6a02e9e8e6811489841a19e |
User & Date: | danielk1977 2005-12-07 06:27:44.000 |
Context
2005-12-08
| ||
18:12 | Provide a pragma to set the codec key. (CVS 2806) (check-in: a7c9e8989c user: drh tags: trunk) | |
2005-12-07
| ||
06:27 | Add some tests for malloc() failure within the column_name() and column_decl() APIs. (CVS 2805) (check-in: 78f10ca0a6 user: danielk1977 tags: trunk) | |
2005-12-06
| ||
17:48 | Allow VACUUM to detach the auxillary database after malloc() fails. (CVS 2804) (check-in: 6824a78bc7 user: danielk1977 tags: trunk) | |
Changes
Changes to src/tclsqlite.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** A TCL Interface to SQLite ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** A TCL Interface to SQLite ** ** $Id: tclsqlite.c,v 1.135 2005/12/07 06:27:44 danielk1977 Exp $ */ #ifndef NO_TCL /* Omit this whole file if TCL is unavailable */ #include "sqliteInt.h" #include "hash.h" #include "tcl.h" #include <stdlib.h> |
︙ | ︙ | |||
398 399 400 401 402 403 404 | } case SQLITE_NULL: { pVal = Tcl_NewStringObj("", 0); break; } default: { int bytes = sqlite3_value_bytes(pIn); | | | 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 | } case SQLITE_NULL: { pVal = Tcl_NewStringObj("", 0); break; } default: { int bytes = sqlite3_value_bytes(pIn); pVal = Tcl_NewStringObj((char *)sqlite3_value_text(pIn), bytes); break; } } rc = Tcl_ListObjAppendElement(p->interp, pCmd, pVal); if( rc ){ Tcl_DecrRefCount(pCmd); sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); |
︙ | ︙ | |||
445 446 447 448 449 450 451 | Tcl_GetDoubleFromObj(0, pVar, &r); sqlite3_result_double(context, r); }else if( c=='w' && strcmp(zType,"wideInt")==0 ){ Tcl_WideInt v; Tcl_GetWideIntFromObj(0, pVar, &v); sqlite3_result_int64(context, v); }else{ | | | | 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 | Tcl_GetDoubleFromObj(0, pVar, &r); sqlite3_result_double(context, r); }else if( c=='w' && strcmp(zType,"wideInt")==0 ){ Tcl_WideInt v; Tcl_GetWideIntFromObj(0, pVar, &v); sqlite3_result_int64(context, v); }else{ data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n); sqlite3_result_text(context, (char *)data, n, SQLITE_TRANSIENT); } } } #ifndef SQLITE_OMIT_AUTHORIZATION /* ** This is the authentication function. It appends the authentication |
︙ | ︙ | |||
1281 1282 1283 1284 1285 1286 1287 | Tcl_GetDoubleFromObj(interp, pVar, &r); sqlite3_bind_double(pStmt, i, r); }else if( c=='w' && strcmp(zType,"wideInt")==0 ){ Tcl_WideInt v; Tcl_GetWideIntFromObj(interp, pVar, &v); sqlite3_bind_int64(pStmt, i, v); }else{ | | | | 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 | Tcl_GetDoubleFromObj(interp, pVar, &r); sqlite3_bind_double(pStmt, i, r); }else if( c=='w' && strcmp(zType,"wideInt")==0 ){ Tcl_WideInt v; Tcl_GetWideIntFromObj(interp, pVar, &v); sqlite3_bind_int64(pStmt, i, v); }else{ data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n); sqlite3_bind_text(pStmt, i, (char *)data, n, SQLITE_STATIC); Tcl_IncrRefCount(pVar); apParm[nParm++] = pVar; } }else{ sqlite3_bind_null( pStmt, i ); } } |
︙ | ︙ | |||
1350 1351 1352 1353 1354 1355 1356 | break; } case SQLITE_NULL: { pVal = dbTextToObj(pDb->zNull); break; } default: { | | | 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 | break; } case SQLITE_NULL: { pVal = dbTextToObj(pDb->zNull); break; } default: { pVal = dbTextToObj((char *)sqlite3_column_text(pStmt, i)); break; } } if( pScript ){ if( pArray==0 ){ Tcl_ObjSetVar2(interp, apColName[i], 0, pVal, 0); |
︙ | ︙ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
54 55 56 57 58 59 60 | int sqlite3_value_int(sqlite3_value *pVal){ return sqlite3VdbeIntValue((Mem*)pVal); } sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){ return sqlite3VdbeIntValue((Mem*)pVal); } const unsigned char *sqlite3_value_text(sqlite3_value *pVal){ | | | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | int sqlite3_value_int(sqlite3_value *pVal){ return sqlite3VdbeIntValue((Mem*)pVal); } sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){ return sqlite3VdbeIntValue((Mem*)pVal); } const unsigned char *sqlite3_value_text(sqlite3_value *pVal){ return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8); } #ifndef SQLITE_OMIT_UTF16 const void *sqlite3_value_text16(sqlite3_value* pVal){ return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE); } const void *sqlite3_value_text16be(sqlite3_value *pVal){ return sqlite3ValueText(pVal, SQLITE_UTF16BE); |
︙ | ︙ | |||
435 436 437 438 439 440 441 442 443 444 445 446 447 448 | */ static const void *columnName( sqlite3_stmt *pStmt, int N, const void *(*xFunc)(Mem*), int useType ){ Vdbe *p = (Vdbe *)pStmt; int n = sqlite3_column_count(pStmt); if( p==0 || N>=n || N<0 ){ return 0; } N += useType*n; | > | > > > > > > | 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 | */ static const void *columnName( sqlite3_stmt *pStmt, int N, const void *(*xFunc)(Mem*), int useType ){ const void *ret; Vdbe *p = (Vdbe *)pStmt; int n = sqlite3_column_count(pStmt); if( p==0 || N>=n || N<0 ){ return 0; } N += useType*n; ret = xFunc(&p->aColName[N]); /* A malloc may have failed inside of the xFunc() call. If this is the case, ** clear the mallocFailed flag and return NULL. */ sqlite3ClearMallocFailed(); return ret; } /* ** Return the name of the Nth column of the result set returned by SQL ** statement pStmt. */ |
︙ | ︙ |
Changes to src/vdbemem.c.
︙ | ︙ | |||
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | int rc; if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){ return SQLITE_OK; } #ifdef SQLITE_OMIT_UTF16 return SQLITE_ERROR; #else rc = sqlite3VdbeMemTranslate(pMem, desiredEnc); if( rc==SQLITE_NOMEM ){ sqlite3VdbeMemRelease(pMem); pMem->flags = MEM_Null; pMem->z = 0; } return rc; #endif } /* ** Make the given Mem object MEM_Dyn. | > > > > > > > > > > | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | int rc; if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){ return SQLITE_OK; } #ifdef SQLITE_OMIT_UTF16 return SQLITE_ERROR; #else /* MemTranslate() may return SQLITE_OK or SQLITE_NOMEM. If NOMEM is returned, ** then the encoding of the value may not have changed. */ rc = sqlite3VdbeMemTranslate(pMem, desiredEnc); assert(rc==SQLITE_OK || rc==SQLITE_NOMEM); assert(rc==SQLITE_OK || pMem->enc!=desiredEnc); assert(rc==SQLITE_NOMEM || pMem->enc==desiredEnc); if( rc==SQLITE_NOMEM ){ /* sqlite3VdbeMemRelease(pMem); pMem->flags = MEM_Null; pMem->z = 0; */ } return rc; #endif } /* ** Make the given Mem object MEM_Dyn. |
︙ | ︙ | |||
742 743 744 745 746 747 748 | return 0; } if( pVal->flags&MEM_Str ){ sqlite3VdbeChangeEncoding(pVal, enc); }else if( !(pVal->flags&MEM_Blob) ){ sqlite3VdbeMemStringify(pVal, enc); } | > | | 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 | return 0; } if( pVal->flags&MEM_Str ){ sqlite3VdbeChangeEncoding(pVal, enc); }else if( !(pVal->flags&MEM_Blob) ){ sqlite3VdbeMemStringify(pVal, enc); } assert(pVal->enc==enc || sqlite3Tsd()->mallocFailed); return (const void *)(pVal->enc==enc ? (pVal->z) : 0); } /* ** Create a new sqlite3_value object. */ sqlite3_value* sqlite3ValueNew(void){ Mem *p = sqliteMalloc(sizeof(*p)); |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is reponsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is reponsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** ** $Id: where.c,v 1.187 2005/12/07 06:27:44 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** The number of bits in a Bitmask. "BMS" means "BitMask Size". */ #define BMS (sizeof(Bitmask)*8) |
︙ | ︙ | |||
517 518 519 520 521 522 523 | pColl = db->pDfltColl; } if( (pColl->type!=SQLITE_COLL_BINARY || noCase) && (pColl->type!=SQLITE_COLL_NOCASE || !noCase) ){ return 0; } sqlite3DequoteExpr(pRight); | | | 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 | pColl = db->pDfltColl; } if( (pColl->type!=SQLITE_COLL_BINARY || noCase) && (pColl->type!=SQLITE_COLL_NOCASE || !noCase) ){ return 0; } sqlite3DequoteExpr(pRight); z = (char *)pRight->token.z; for(cnt=0; (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2]; cnt++){} if( cnt==0 || 255==(u8)z[cnt] ){ return 0; } *pisComplete = z[cnt]==wc[0] && z[cnt+1]==0; *pnPattern = cnt; return 1; |
︙ | ︙ |
Changes to test/malloc3.test.
1 2 3 4 5 6 7 8 9 10 11 | # 2005 November 30 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # | > > > > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # 2005 November 30 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # This file contains tests to ensure that the library handles malloc() failures # correctly. The emphasis of these tests are the _prepare(), _step() and # _finalize() calls. # # $Id: malloc3.test,v 1.3 2005/12/07 06:27:45 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]==""} { puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..." |
︙ | ︙ | |||
449 450 451 452 453 454 455 | do_test $testid { execsql { SELECT * FROM v1 WHERE d = g; } } {a b c a b c 1 2 3 1 2 3} } | | | 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 | do_test $testid { execsql { SELECT * FROM v1 WHERE d = g; } } {a b c a b c 1 2 3 1 2 3} } # Test a simple multi-file transaction # file delete -force test2.db SQL {ATTACH 'test2.db' AS aux;} SQL {BEGIN} SQL {CREATE TABLE aux.tbl2(x, y, z)} SQL {INSERT INTO tbl2 VALUES(1, 2, 3)} SQL {INSERT INTO def VALUES(4, 5, 6)} |
︙ | ︙ |
Added test/malloc4.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | # 2005 November 30 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # This file contains tests to ensure that the library handles malloc() failures # correctly. The emphasis in this file is on sqlite3_column_XXX() APIs. # # $Id: malloc4.test,v 1.1 2005/12/07 06:27:45 danielk1977 Exp $ #--------------------------------------------------------------------------- # NOTES ON EXPECTED BEHAVIOUR # #--------------------------------------------------------------------------- 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]==""} { puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..." finish_test return } proc do_stmt_test {id sql} { set ::sql $sql set go 1 for {set n 1} {$go} {incr n} { set testid "malloc4-$id.(iFail $n)" # Prepare the statement do_test ${testid}.1 { set ::STMT [sqlite3_prepare $::DB $sql -1 TAIL] expr [string length $::STMT] > 0 } {1} # Set the Nth malloc() to fail. sqlite_malloc_fail $n # Test malloc failure in the _name(), _name16(), decltype() and # decltype16() APIs. Calls that occur after the malloc() failure should # return NULL. No error is raised though. do_test ${testid}.2.1 { set mf1 [expr [lindex [sqlite_malloc_stat] 2] <= 0] set ::name8 [sqlite3_column_name $::STMT 0] set mf2 [expr [lindex [sqlite_malloc_stat] 2] <= 0] expr {$mf1 == $mf2 || $::name8 == ""} } {1} do_test ${testid}.2.2 { set mf1 [expr [lindex [sqlite_malloc_stat] 2] <= 0] set ::name16 [sqlite3_column_name16 $::STMT 0] set ::name16 [encoding convertfrom unicode $::name16] set ::name16 [string range $::name16 0 end-1] set mf2 [expr [lindex [sqlite_malloc_stat] 2] <= 0] expr {$mf1 == $mf2 || $::name16 == ""} } {1} do_test ${testid}.2.3 { set mf1 [expr [lindex [sqlite_malloc_stat] 2] <= 0] set ::name8_2 [sqlite3_column_name $::STMT 0] set mf2 [expr [lindex [sqlite_malloc_stat] 2] <= 0] expr {$mf1 == $mf2 || $::name8_2 == ""} } {1} set ::mallocFailed [expr [lindex [sqlite_malloc_stat] 2] <= 0] do_test ${testid}.2.4 { expr { $::name8 == $::name8_2 && $::name16 == $::name8 && !$::mallocFailed || $::name8 == $::name8_2 && $::name16 == "" && $::mallocFailed || $::name8 == $::name16 && $::name8_2 == "" && $::mallocFailed || $::name8_2 == $::name16 && $::name8 == "" && $::mallocFailed } } {1} if {$::mallocFailed == 0} { sqlite_malloc_fail 0 set go 0 } if 0 { # Test that if a malloc() failed the next call to sqlite3_step() returns # SQLITE_ERROR. If malloc() did not fail, it should return SQLITE_ROW. # # Before running sqlite3_step(), make sure that malloc() is not about to # fail. Memory allocation failures that occur within sqlite3_step() are # tested elsewhere. do_test ${testid}.3 { set rc [sqlite3_step $::STMT] list [expr $rc=="SQLITE_ERROR"] [expr $rc=="SQLITE_ROW"] } [list $mallocFailed [expr !$mallocFailed]] } do_test ${testid}.4 { sqlite3_finalize $::STMT } {SQLITE_OK} } } execsql { CREATE TABLE tbl( the_first_reasonably_long_column_name that_also_has_quite_a_lengthy_type ); } do_stmt_test 1 "SELECT * FROM tbl" sqlite_malloc_fail 0 finish_test |
Changes to test/quick.test.
|
| < < < < | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file runs all tests. # # $Id: quick.test,v 1.37 2005/12/07 06:27:45 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl rename finish_test really_finish_test proc finish_test {} {} set ISQUICK 1 set EXCLUDE { all.test btree2.test btree3.test btree4.test btree5.test btree6.test corrupt.test crash.test malloc.test malloc2.test malloc3.test malloc4.test memleak.test misuse.test quick.test utf16.test autovacuum_crash.test btree8.test } |
︙ | ︙ |