Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a potential segfault following a malloc() failure during a call to sqlite3_prepare() where the nBytes parameter is positive but less than the length of the input SQL string. (CVS 3888) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
27bf3fc3cf3c9c7acdbf9281a4669c9f |
User & Date: | drh 2007-04-30 21:39:16.000 |
Context
2007-04-30
| ||
22:09 | Propagate prefix flag through implementation of doclist query code. Also implement correct prefix-handling for traversal of interior nodes of segment tree. A given prefix can span multiple children of an interior node, and from there the branches need to be followed in parallel. (CVS 3889) (check-in: cae844a01a user: shess tags: trunk) | |
21:39 | Fix a potential segfault following a malloc() failure during a call to sqlite3_prepare() where the nBytes parameter is positive but less than the length of the input SQL string. (CVS 3888) (check-in: 27bf3fc3cf user: drh tags: trunk) | |
17:52 | Lift docListMerge() call out of loadSegmentLeavesInt() for prefix search. Doclists from multiple prefix matches will need a union merge function, which will have to logically happen across a segment before doclists are merged between segments. (CVS 3887) (check-in: 7ddb826689 user: shess tags: trunk) | |
Changes
Changes to src/prepare.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the implementation of the sqlite3_prepare() ** interface, and routines that contribute to loading the database schema ** from disk. ** | | | 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. ** ************************************************************************* ** This file contains the implementation of the sqlite3_prepare() ** interface, and routines that contribute to loading the database schema ** from disk. ** ** $Id: prepare.c,v 1.47 2007/04/30 21:39:16 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* ** Fill the InitData structure with an error message that indicates |
︙ | ︙ | |||
487 488 489 490 491 492 493 | } } memset(&sParse, 0, sizeof(sParse)); sParse.db = db; if( nBytes>=0 && zSql[nBytes]!=0 ){ char *zSqlCopy = sqlite3StrNDup(zSql, nBytes); | > | < | > > | 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 | } } memset(&sParse, 0, sizeof(sParse)); sParse.db = db; if( nBytes>=0 && zSql[nBytes]!=0 ){ char *zSqlCopy = sqlite3StrNDup(zSql, nBytes); if( zSqlCopy ){ sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg); sqliteFree(zSqlCopy); } sParse.zTail = &zSql[nBytes]; }else{ sqlite3RunParser(&sParse, zSql, &zErrMsg); } if( sqlite3MallocFailed() ){ sParse.rc = SQLITE_NOMEM; } |
︙ | ︙ |
Changes to test/malloc8.test.
|
| | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2007 April 25 # # 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 additional out-of-memory checks (see malloc.tcl) # added to expose a bug in out-of-memory handling for sqlite3_value_text() # # $Id: malloc8.test,v 1.2 2007/04/30 21:39:16 drh 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]==""} { |
︙ | ︙ |
Added test/malloc9.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 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | # 2007 April 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 additional out-of-memory checks (see malloc.tcl) # added to expose a bug in out-of-memory handling for sqlite3_prepare(). # # $Id: malloc9.test,v 1.1 2007/04/30 21:39:16 drh 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..." finish_test return } # Usage: do_malloc_test <test number> <options...> # # The first argument, <test number>, is an integer used to name the # tests executed by this proc. Options are as follows: # # -tclprep TCL script to run to prepare test. # -sqlprep SQL script to run to prepare test. # -tclbody TCL script to run with malloc failure simulation. # -sqlbody TCL script to run with malloc failure simulation. # -cleanup TCL script to run after the test. # # This command runs a series of tests to verify SQLite's ability # to handle an out-of-memory condition gracefully. It is assumed # that if this condition occurs a malloc() call will return a # NULL pointer. Linux, for example, doesn't do that by default. See # the "BUGS" section of malloc(3). # # Each iteration of a loop, the TCL commands in any argument passed # to the -tclbody switch, followed by the SQL commands in any argument # passed to the -sqlbody switch are executed. Each iteration the # Nth call to sqliteMalloc() is made to fail, where N is increased # each time the loop runs starting from 1. When all commands execute # successfully, the loop ends. # proc do_malloc_test {tn args} { array unset ::mallocopts array set ::mallocopts $args set ::go 1 for {set ::n 1} {$::go && $::n < 50000} {incr ::n} { do_test malloc9-$tn.$::n { sqlite_malloc_fail 0 catch {db close} catch {file delete -force test.db} catch {file delete -force test.db-journal} sqlite3 db test.db set ::DB [sqlite3_connection_pointer db] # Execute any -tclprep and -sqlprep scripts. # if {[info exists ::mallocopts(-tclprep)]} { eval $::mallocopts(-tclprep) } if {[info exists ::mallocopts(-sqlprep)]} { execsql $::mallocopts(-sqlprep) } # Now set the ${::n}th malloc() to fail and execute the -tclbody and # -sqlbody scripts. # sqlite_malloc_fail $::n set ::mallocbody {} if {[info exists ::mallocopts(-tclbody)]} { append ::mallocbody "$::mallocopts(-tclbody)\n" } if {[info exists ::mallocopts(-sqlbody)]} { append ::mallocbody "db eval {$::mallocopts(-sqlbody)}" } set v [catch $::mallocbody msg] # If the test fails (if $v!=0) and the database connection actually # exists, make sure the failure code is SQLITE_NOMEM. if {$v && [info command db]=="db" && [info exists ::mallocopts(-sqlbody)] && [db errorcode]!=7} { set v 999 } set leftover [lindex [sqlite_malloc_stat] 2] if {$leftover>0} { if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"} set ::go 0 if {$v} { puts "\nError message returned: $msg" } else { set v {1 1} } } else { set v2 [expr {$msg=="" || [regexp {out of memory} $msg]}] 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 { set sql {CREATE TABLE t1(x)} set sqlbytes [string length $sql] append sql {; INSERT INTO t1 VALUES(1)} } -tclbody { if {[catch {sqlite3_prepare db $sql $sqlbytes TAIL} STMT]} { set msg $STMT set STMT {} error $msg } } -cleanup { if {$STMT!=""} { sqlite3_finalize $STMT } } # 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 |