/ Check-in [86eab9e5]
Login

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 | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 86eab9e53db8d7fecc789fe3d8cd8d7be3196fed
User & Date: danielk1977 2006-01-18 05:51:58
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: 8830bbba user: drh tags: trunk
05:51
Handle malloc() failures that occur in open16() and errmsg16(). (CVS 2967) check-in: 86eab9e5 user: danielk1977 tags: trunk
04:26
Handle malloc() failures that occur inside create_collation() calls. (CVS 2966) check-in: 95c5903f user: danielk1977 tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/main.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** Main file for the SQLite library.  The routines in this file
    13     13   ** implement the programmer interface to the library.  Routines in
    14     14   ** other files are for internal use by SQLite and should not be
    15     15   ** accessed by users of the library.
    16     16   **
    17         -** $Id: main.c,v 1.325 2006/01/18 04:26:07 danielk1977 Exp $
           17  +** $Id: main.c,v 1.326 2006/01/18 05:51:58 danielk1977 Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include "os.h"
    21     21   #include <ctype.h>
    22     22   
    23     23   /*
    24     24   ** The following constant value is used by the SQLITE_BIGENDIAN and
................................................................................
   723    723     }
   724    724     z = sqlite3_value_text16(db->pErr);
   725    725     if( z==0 ){
   726    726       sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode),
   727    727            SQLITE_UTF8, SQLITE_STATIC);
   728    728       z = sqlite3_value_text16(db->pErr);
   729    729     }
          730  +  sqlite3MallocClearFailed();
   730    731     return z;
   731    732   }
   732    733   #endif /* SQLITE_OMIT_UTF16 */
   733    734   
   734    735   /*
   735    736   ** Return the most recent error code generated by an SQLite routine. If NULL is
   736    737   ** passed to this function, we assume a malloc() failed during sqlite3_open().
................................................................................
   926    927     pVal = sqlite3ValueNew();
   927    928     sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC);
   928    929     zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8);
   929    930     if( zFilename8 ){
   930    931       rc = openDatabase(zFilename8, ppDb);
   931    932       if( rc==SQLITE_OK && *ppDb ){
   932    933         rc = sqlite3_exec(*ppDb, "PRAGMA encoding = 'UTF-16'", 0, 0, 0);
          934  +      if( rc!=SQLITE_OK ){
          935  +        sqlite3_close(*ppDb);
          936  +        *ppDb = 0;
          937  +      }
   933    938       }
   934    939     }else{
   935    940       assert( sqlite3ThreadDataReadOnly()->mallocFailed );
   936    941       sqlite3MallocClearFailed();
   937    942     }
   938    943     sqlite3ValueFree(pVal);
   939    944   

Changes to src/test1.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Code for testing the printf() interface to SQLite.  This code
    13     13   ** is not included in the SQLite library.  It is used for automated
    14     14   ** testing of the SQLite library.
    15     15   **
    16         -** $Id: test1.c,v 1.194 2006/01/18 04:26:07 danielk1977 Exp $
           16  +** $Id: test1.c,v 1.195 2006/01/18 05:51:58 danielk1977 Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   #include "tcl.h"
    20     20   #include "os.h"
    21     21   #include <stdlib.h>
    22     22   #include <string.h>
    23     23   
................................................................................
  2045   2045     Tcl_Interp *interp,
  2046   2046     int objc,
  2047   2047     Tcl_Obj *CONST objv[]
  2048   2048   ){
  2049   2049   #ifndef SQLITE_OMIT_UTF16
  2050   2050     sqlite3 *db;
  2051   2051     const void *zErr;
  2052         -  int bytes;
         2052  +  int bytes = 0;
  2053   2053   
  2054   2054     if( objc!=2 ){
  2055   2055       Tcl_AppendResult(interp, "wrong # args: should be \"", 
  2056   2056          Tcl_GetString(objv[0]), " DB", 0);
  2057   2057       return TCL_ERROR;
  2058   2058     }
  2059   2059     if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  2060   2060   
  2061   2061     zErr = sqlite3_errmsg16(db);
  2062         -  bytes = sqlite3utf16ByteLen(zErr, -1);
         2062  +  if( zErr ){
         2063  +    bytes = sqlite3utf16ByteLen(zErr, -1);
         2064  +  }
  2063   2065     Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(zErr, bytes));
  2064   2066   #endif /* SQLITE_OMIT_UTF16 */
  2065   2067     return TCL_OK;
  2066   2068   }
  2067   2069   
  2068   2070   /*
  2069   2071   ** Usage: sqlite3_prepare DB sql bytes tailvar

Changes to src/vdbeapi.c.

   776    776       || (pTo->magic!=VDBE_MAGIC_RUN && pTo->magic!=VDBE_MAGIC_HALT) ){
   777    777       return SQLITE_MISUSE;
   778    778     }
   779    779     if( pFrom->nVar!=pTo->nVar ){
   780    780       return SQLITE_ERROR;
   781    781     }
   782    782     for(i=0; rc==SQLITE_OK && i<pFrom->nVar; i++){
          783  +    sqlite3MallocDisallow();
   783    784       rc = sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]);
          785  +    sqlite3MallocAllow();
   784    786     }
   785    787     return rc;
   786    788   }
   787    789   
   788    790   /*
   789    791   ** Return the sqlite3* database handle to which the prepared statement given
   790    792   ** in the argument belongs.  This is the same database handle that was
   791    793   ** the first argument to the sqlite3_prepare() that was used to create
   792    794   ** the statement in the first place.
   793    795   */
   794    796   sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){
   795    797     return pStmt ? ((Vdbe*)pStmt)->db : 0;
   796    798   }

Changes to test/malloc.test.

    10     10   #***********************************************************************
    11     11   # This file attempts to check the library in an out-of-memory situation.
    12     12   # When compiled with -DSQLITE_DEBUG=1, the SQLite library accepts a special
    13     13   # command (sqlite_malloc_fail N) which causes the N-th malloc to fail.  This
    14     14   # special feature is used to see what happens in the library if a malloc
    15     15   # were to really fail due to an out-of-memory situation.
    16     16   #
    17         -# $Id: malloc.test,v 1.28 2006/01/18 04:26:08 danielk1977 Exp $
           17  +# $Id: malloc.test,v 1.29 2006/01/18 05:51:58 danielk1977 Exp $
    18     18   
    19     19   set testdir [file dirname $argv0]
    20     20   source $testdir/tester.tcl
    21     21   
    22     22   # Only run these tests if memory debugging is turned on.
    23     23   #
    24     24   if {[info command sqlite_malloc_stat]==""} {
................................................................................
   106    106           set v2 [expr {$msg=="" || $msg=="out of memory"}]
   107    107           if {!$v2} {puts "\nError message returned: $msg"}
   108    108           lappend v $v2
   109    109         }
   110    110       } {1 1}
   111    111   
   112    112       if {[info exists ::mallocopts(-cleanup)]} {
   113         -      catch $::mallocopts(-cleanup)
          113  +      catch [list uplevel #0 $::mallocopts(-cleanup)] msg
   114    114       }
   115    115     }
   116    116     unset ::mallocopts
   117    117   }
   118    118   
   119    119   do_malloc_test 1 -tclprep {
   120    120     db close
................................................................................
   355    355         CREATE TABLE aux.t2(a, b, c);
   356    356         CREATE TABLE t1(a, b, c);
   357    357         COMMIT;
   358    358       }]
   359    359       if {$rc!="1 {child process exited abnormally}"} {
   360    360         error "Wrong error message: $rc"
   361    361       }
   362         -  } -sqlbody {
   363         -    ATTACH 'test2.db' as aux;
   364         -    SELECT * FROM t1;
   365         -    SELECT * FROM t2;
          362  +  } -tclbody {
          363  +    db eval {ATTACH 'test2.db' as aux;}
          364  +    set rc [catch {db eval {
          365  +      SELECT * FROM t1; 
          366  +      SELECT * FROM t2;
          367  +    }} err]
          368  +    if {$rc && $err!="no such table: t1"} {
          369  +      error $err
          370  +    }
   366    371     }
   367    372   }
   368    373   
   369    374   if {$tcl_platform(platform)!="windows"} {
   370    375     do_malloc_test 14 -tclprep {
   371    376       catch {db close}
   372    377       sqlite3 db2 test2.db
................................................................................
   390    395   
   391    396   proc string_compare {a b} {
   392    397     return [string compare $a $b]
   393    398   }
   394    399   
   395    400   # Test for malloc() failures in sqlite3_create_collation() and 
   396    401   # sqlite3_create_collation16().
          402  +#
   397    403   do_malloc_test 15 -tclbody {
   398    404     db collate string_compare string_compare
   399    405     if {[catch {add_test_collate $::DB 1 1 1} msg]} {
   400    406       if {$msg=="SQLITE_NOMEM"} {set msg "out of memory"}
   401    407       error $msg
   402    408     }
          409  +
          410  +  db complete {SELECT "hello """||'world"' [microsoft], * FROM anicetable;}
          411  +  db complete {-- Useful comment}
          412  +
   403    413     execsql {
   404    414       CREATE TABLE t1(a, b COLLATE string_compare);
   405    415       INSERT INTO t1 VALUES(10, 'string');
   406    416       INSERT INTO t1 VALUES(10, 'string2');
   407    417     }
   408    418   }
          419  +
          420  +# Also test sqlite3_complete(). There are (currently) no malloc()
          421  +# calls in this function, but test anyway against future changes.
          422  +#
          423  +do_malloc_test 16 -tclbody {
          424  +  db complete {SELECT "hello """||'world"' [microsoft], * FROM anicetable;}
          425  +  db complete {-- Useful comment}
          426  +  db eval {
          427  +    SELECT * FROM sqlite_master;
          428  +  }
          429  +}
          430  +
          431  +# Test handling of malloc() failures in sqlite3_open16().
          432  +#
          433  +do_malloc_test 17 -tclbody {
          434  +  set DB2 0
          435  +  set STMT 0
          436  +
          437  +  # open database using sqlite3_open16()
          438  +  set DB2 [sqlite3_open16 test.db -unused]
          439  +  if {0==$DB2} {
          440  +    error "out of memory"
          441  +  }
          442  +
          443  +  # Prepare statement
          444  +  set rc [catch {sqlite3_prepare $DB2 {SELECT * FROM sqlite_master} -1 X} msg]
          445  +  if {$rc} {
          446  +    error [string range $msg 4 end]
          447  +  }
          448  +  set STMT $msg
          449  +
          450  +  # Finalize statement
          451  +  set rc [sqlite3_finalize $STMT]
          452  +  if {$rc!="SQLITE_OK"} {
          453  +    error [sqlite3_errmsg $DB2]
          454  +  }
          455  +  set STMT 0
          456  +
          457  +  # Close database
          458  +  set rc [sqlite3_close $DB2]
          459  +  if {$rc!="SQLITE_OK"} {
          460  +    error [sqlite3_errmsg $DB2]
          461  +  }
          462  +  set DB2 0
          463  +} -cleanup {
          464  +  if {$STMT!="0"} {
          465  +    sqlite3_finalize $STMT
          466  +  }
          467  +  if {$DB2!="0"} {
          468  +    set rc [sqlite3_close $DB2]
          469  +  }
          470  +}
          471  +
          472  +# Test handling of malloc() failures in sqlite3_errmsg16().
          473  +#
          474  +do_malloc_test 18 -tclbody {
          475  +  catch {
          476  +    db eval "SELECT [string repeat longcolumnname 10] FROM sqlite_master"
          477  +  } msg
          478  +  if {$msg=="out of memory"} {error $msg}
          479  +  set utf16 [sqlite3_errmsg16 [sqlite3_connection_pointer db]]
          480  +  binary scan $utf16 c* bytes
          481  +  if {[llength $bytes]==0} {
          482  +    error "out of memory"
          483  +  }
          484  +}
   409    485   
   410    486   # Ensure that no file descriptors were leaked.
   411    487   do_test malloc-99.X {
   412    488     catch {db close}
   413    489     set sqlite_open_file_count
   414    490   } {0}
   415    491   
   416    492   sqlite_malloc_fail 0
   417    493   finish_test