| OLD | NEW | 
 | (Empty) | 
|    1 # 2005 November 30 |  | 
|    2 # |  | 
|    3 # The author disclaims copyright to this source code.  In place of |  | 
|    4 # a legal notice, here is a blessing: |  | 
|    5 # |  | 
|    6 #    May you do good and not evil. |  | 
|    7 #    May you find forgiveness for yourself and forgive others. |  | 
|    8 #    May you share freely, never taking more than you give. |  | 
|    9 # |  | 
|   10 #*********************************************************************** |  | 
|   11 # |  | 
|   12 # This file contains tests to ensure that the library handles malloc() failures |  | 
|   13 # correctly. The emphasis in this file is on sqlite3_column_XXX() APIs. |  | 
|   14 # |  | 
|   15 # $Id: malloc4.test,v 1.10 2008/02/18 22:24:58 drh Exp $ |  | 
|   16  |  | 
|   17 #--------------------------------------------------------------------------- |  | 
|   18 # NOTES ON EXPECTED BEHAVIOUR |  | 
|   19 # |  | 
|   20 # [193] When a memory allocation failure occurs during sqlite3_column_name(), |  | 
|   21 #       sqlite3_column_name16(), sqlite3_column_decltype(), or |  | 
|   22 #       sqlite3_column_decltype16() the function shall return NULL. |  | 
|   23 # |  | 
|   24 #--------------------------------------------------------------------------- |  | 
|   25  |  | 
|   26 set testdir [file dirname $argv0] |  | 
|   27 source $testdir/tester.tcl |  | 
|   28 source $testdir/malloc_common.tcl |  | 
|   29  |  | 
|   30 # Only run these tests if memory debugging is turned on. |  | 
|   31 if {!$MEMDEBUG} { |  | 
|   32    puts "Skipping malloc4 tests: not compiled with -DSQLITE_MEMDEBUG..." |  | 
|   33    finish_test |  | 
|   34    return |  | 
|   35 } |  | 
|   36  |  | 
|   37 ifcapable !utf16 { |  | 
|   38   finish_test |  | 
|   39   return |  | 
|   40 } |  | 
|   41  |  | 
|   42 proc do_stmt_test {id sql} { |  | 
|   43   set ::sql $sql |  | 
|   44   set go 1 |  | 
|   45   for {set n 0} {$go} {incr n} { |  | 
|   46     set testid "malloc4-$id.$n" |  | 
|   47  |  | 
|   48     # Prepare the statement |  | 
|   49     do_test ${testid}.1 { |  | 
|   50       set ::STMT [sqlite3_prepare $::DB $sql -1 TAIL] |  | 
|   51       expr [string length $::STMT] > 0 |  | 
|   52     } {1} |  | 
|   53  |  | 
|   54     # Set the Nth malloc() to fail. |  | 
|   55     sqlite3_memdebug_fail $n -repeat 0 |  | 
|   56  |  | 
|   57     # Test malloc failure in the _name(), _name16(), decltype() and |  | 
|   58     # decltype16() APIs. Calls that occur after the malloc() failure should |  | 
|   59     # return NULL. No error is raised though. |  | 
|   60     # |  | 
|   61     # ${testid}.2.1 - Call _name() |  | 
|   62     # ${testid}.2.2 - Call _name16() |  | 
|   63     # ${testid}.2.3 - Call _name() |  | 
|   64     # ${testid}.2.4 - Check that the return values of the above three calls are |  | 
|   65     #                 consistent with each other and with the simulated |  | 
|   66     #                 malloc() failures. |  | 
|   67     # |  | 
|   68     # Because the code that implements the _decltype() and _decltype16() APIs |  | 
|   69     # is the same as the _name() and _name16() implementations, we don't worry |  | 
|   70     # about explicitly testing them. |  | 
|   71     # |  | 
|   72     do_test ${testid}.2.1 { |  | 
|   73       set mf1 [expr [sqlite3_memdebug_pending] < 0] |  | 
|   74       set ::name8  [sqlite3_column_name $::STMT 0] |  | 
|   75       set mf2 [expr [sqlite3_memdebug_pending] < 0] |  | 
|   76       expr {$mf1 == $mf2 || $::name8 == ""} |  | 
|   77     } {1} |  | 
|   78     do_test ${testid}.2.2 { |  | 
|   79       set mf1 [expr [sqlite3_memdebug_pending] < 0] |  | 
|   80       set ::name16 [sqlite3_column_name16 $::STMT 0] |  | 
|   81       set ::name16 [encoding convertfrom unicode $::name16] |  | 
|   82       set ::name16 [string range $::name16 0 end-1] |  | 
|   83       set mf2 [expr [sqlite3_memdebug_pending] < 0] |  | 
|   84       expr {$mf1 == $mf2 || $::name16 == ""} |  | 
|   85     } {1} |  | 
|   86     do_test ${testid}.2.3 { |  | 
|   87       set mf1 [expr [sqlite3_memdebug_pending] < 0] |  | 
|   88       set ::name8_2 [sqlite3_column_name $::STMT 0] |  | 
|   89       set mf2 [expr [sqlite3_memdebug_pending] < 0] |  | 
|   90       expr {$mf1 == $mf2 || $::name8_2 == ""} |  | 
|   91     } {1} |  | 
|   92     set ::mallocFailed [expr [sqlite3_memdebug_pending] < 0] |  | 
|   93     do_test ${testid}.2.4 { |  | 
|   94       expr { |  | 
|   95         $::name8 == $::name8_2 && $::name16 == $::name8 && !$::mallocFailed || |  | 
|   96         $::name8 == $::name8_2 && $::name16 == "" &&        $::mallocFailed || |  | 
|   97         $::name8 == $::name16 && $::name8_2 == "" &&        $::mallocFailed || |  | 
|   98         $::name8_2 == $::name16 && $::name8 == "" &&        $::mallocFailed |  | 
|   99       } |  | 
|  100     } {1} |  | 
|  101  |  | 
|  102     # Step the statement so that we can call _text() and _text16().  Before |  | 
|  103     # running sqlite3_step(), make sure that malloc() is not about to fail. |  | 
|  104     # Memory allocation failures that occur within sqlite3_step() are tested |  | 
|  105     # elsewhere. |  | 
|  106     set mf [sqlite3_memdebug_pending] |  | 
|  107     sqlite3_memdebug_fail -1 |  | 
|  108     do_test ${testid}.3 { |  | 
|  109       sqlite3_step $::STMT |  | 
|  110     } {SQLITE_ROW} |  | 
|  111     sqlite3_memdebug_fail $mf |  | 
|  112  |  | 
|  113     # Test for malloc() failures within _text() and _text16(). |  | 
|  114     # |  | 
|  115     do_test ${testid}.4.1 { |  | 
|  116       set ::text8 [sqlite3_column_text $::STMT 0] |  | 
|  117       set mf [expr [sqlite3_memdebug_pending] < 0 && !$::mallocFailed] |  | 
|  118       expr {$mf==0 || $::text8 == ""} |  | 
|  119     } {1} |  | 
|  120     do_test ${testid}.4.2 { |  | 
|  121       set ::text16 [sqlite3_column_text16 $::STMT 0] |  | 
|  122       set ::text16 [encoding convertfrom unicode $::text16] |  | 
|  123       set ::text16 [string range $::text16 0 end-1] |  | 
|  124       set mf [expr [sqlite3_memdebug_pending] < 0 && !$::mallocFailed] |  | 
|  125       expr {$mf==0 || $::text16 == ""} |  | 
|  126     } {1} |  | 
|  127     do_test ${testid}.4.3 { |  | 
|  128       set ::text8_2 [sqlite3_column_text $::STMT 0] |  | 
|  129       set mf [expr [sqlite3_memdebug_pending] < 0 && !$::mallocFailed] |  | 
|  130       expr {$mf==0 || $::text8_2 == "" || ($::text16 == "" && $::text8 != "")} |  | 
|  131     } {1} |  | 
|  132  |  | 
|  133     # Test for malloc() failures within _int(), _int64() and _real(). The only |  | 
|  134     # way this can occur is if the string has to be translated from UTF-16 to |  | 
|  135     # UTF-8 before being converted to a numeric value. |  | 
|  136     do_test ${testid}.4.4.1 { |  | 
|  137       set mf [sqlite3_memdebug_pending] |  | 
|  138       sqlite3_memdebug_fail -1 |  | 
|  139       sqlite3_column_text16 $::STMT 0 |  | 
|  140       sqlite3_memdebug_fail $mf |  | 
|  141       sqlite3_column_int $::STMT 0 |  | 
|  142     } {0} |  | 
|  143     do_test ${testid}.4.5 { |  | 
|  144       set mf [sqlite3_memdebug_pending] |  | 
|  145       sqlite3_memdebug_fail -1 |  | 
|  146       sqlite3_column_text16 $::STMT 0 |  | 
|  147       sqlite3_memdebug_fail $mf |  | 
|  148       sqlite3_column_int64 $::STMT 0 |  | 
|  149     } {0} |  | 
|  150  |  | 
|  151     do_test ${testid}.4.6 { |  | 
|  152       set mf [sqlite3_memdebug_pending] |  | 
|  153       sqlite3_memdebug_fail -1 |  | 
|  154       sqlite3_column_text16 $::STMT 0 |  | 
|  155       sqlite3_memdebug_fail $mf |  | 
|  156       sqlite3_column_double $::STMT 0 |  | 
|  157     } {0.0} |  | 
|  158  |  | 
|  159     set mallocFailedAfterStep [expr \ |  | 
|  160       [sqlite3_memdebug_pending] < 0 && !$::mallocFailed |  | 
|  161     ] |  | 
|  162  |  | 
|  163     sqlite3_memdebug_fail -1 |  | 
|  164     # Test that if a malloc() failed the next call to sqlite3_step() returns |  | 
|  165     # SQLITE_ERROR. If malloc() did not fail, it should return SQLITE_DONE. |  | 
|  166     # |  | 
|  167     do_test ${testid}.5 { |  | 
|  168       sqlite3_step $::STMT |  | 
|  169     } [expr {$mallocFailedAfterStep ? "SQLITE_ERROR" : "SQLITE_DONE"}] |  | 
|  170  |  | 
|  171     do_test ${testid}.6 { |  | 
|  172       sqlite3_finalize $::STMT |  | 
|  173     } [expr {$mallocFailedAfterStep ? "SQLITE_NOMEM" : "SQLITE_OK"}] |  | 
|  174  |  | 
|  175     if {$::mallocFailed == 0 && $mallocFailedAfterStep == 0} { |  | 
|  176       sqlite3_memdebug_fail -1 |  | 
|  177       set go 0 |  | 
|  178     } |  | 
|  179   } |  | 
|  180 } |  | 
|  181  |  | 
|  182 execsql { |  | 
|  183   CREATE TABLE tbl( |  | 
|  184     the_first_reasonably_long_column_name that_also_has_quite_a_lengthy_type |  | 
|  185   ); |  | 
|  186   INSERT INTO tbl VALUES( |  | 
|  187     'An extra long string. Far too long to be stored in NBFS bytes.' |  | 
|  188   ); |  | 
|  189 } |  | 
|  190  |  | 
|  191 do_stmt_test 1 "SELECT * FROM tbl" |  | 
|  192  |  | 
|  193 sqlite3_memdebug_fail -1 |  | 
|  194 finish_test |  | 
| OLD | NEW |