/ Check-in [8795d11c]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix a bug whereby sqlite3_prepare_v2() could return both an out-of-memory error and a valid statement handle. (CVS 3858)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 8795d11c3c5bb39d34bc5194621ce97097a320e7
User & Date: danielk1977 2007-04-19 11:09:01
Context
2007-04-19
12:30
Comment changes in the ioerr tests. No changes to code. (CVS 3859) check-in: b7ed0e1e user: drh tags: trunk
11:09
Fix a bug whereby sqlite3_prepare_v2() could return both an out-of-memory error and a valid statement handle. (CVS 3858) check-in: 8795d11c user: danielk1977 tags: trunk
00:24
Get the build working with SQLITE_OMIT_SHARED_CACHE. Ticket #2307. (CVS 3857) check-in: b623538c user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/prepare.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
533
534
535
536
537
538
539
540

541
542
543

544
545


546
547
548
549
550
551
552
553
**    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.45 2007/03/26 22:05:02 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** Fill the InitData structure with an error message that indicates
................................................................................
    }
  }
#endif

  if( sqlite3SafetyOff(db) ){
    rc = SQLITE_MISUSE;
  }
  if( rc==SQLITE_OK ){

    if( saveSqlFlag ){
      sqlite3VdbeSetSql(sParse.pVdbe, zSql, sParse.zTail - zSql);
    }

    *ppStmt = (sqlite3_stmt*)sParse.pVdbe;
  }else if( sParse.pVdbe ){


    sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe);
  }

  if( zErrMsg ){
    sqlite3Error(db, rc, "%s", zErrMsg);
    sqliteFree(zErrMsg);
  }else{
    sqlite3Error(db, rc, 0);







|







 







<
>
|
|
|
>
|
<
>
>
|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
533
534
535
536
537
538
539

540
541
542
543
544
545

546
547
548
549
550
551
552
553
554
555
**    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.46 2007/04/19 11:09:01 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** Fill the InitData structure with an error message that indicates
................................................................................
    }
  }
#endif

  if( sqlite3SafetyOff(db) ){
    rc = SQLITE_MISUSE;
  }


  if( saveSqlFlag ){
    sqlite3VdbeSetSql(sParse.pVdbe, zSql, sParse.zTail - zSql);
  }
  if( rc!=SQLITE_OK || sqlite3MallocFailed() ){
    sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe);

    assert(!(*ppStmt));
  }else{
    *ppStmt = (sqlite3_stmt*)sParse.pVdbe;
  }

  if( zErrMsg ){
    sqlite3Error(db, rc, "%s", zErrMsg);
    sqliteFree(zErrMsg);
  }else{
    sqlite3Error(db, rc, 0);

Changes to src/test1.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
....
2744
2745
2746
2747
2748
2749
2750

2751
2752
2753
2754
2755
2756
2757
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing all sorts of SQLite interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.237 2007/04/13 02:14:30 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
    return TCL_ERROR;
  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  zSql = Tcl_GetString(objv[2]);
  if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;

  rc = sqlite3_prepare_v2(db, zSql, bytes, &pStmt, &zTail);

  if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
  if( zTail ){
    if( bytes>=0 ){
      bytes = bytes - (zTail-zSql);
    }
    Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0);
  }







|







 







>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
....
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing all sorts of SQLite interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.238 2007/04/19 11:09:02 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
    return TCL_ERROR;
  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  zSql = Tcl_GetString(objv[2]);
  if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;

  rc = sqlite3_prepare_v2(db, zSql, bytes, &pStmt, &zTail);
  assert(rc==SQLITE_OK || pStmt==0);
  if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
  if( zTail ){
    if( bytes>=0 ){
      bytes = bytes - (zTail-zSql);
    }
    Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0);
  }

Changes to test/malloc.test.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
547
548
549
550
551
552
553

















554
555
556
557
558
559
560
561
562
563
#***********************************************************************
# 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.40 2007/03/30 07:10:52 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]==""} {
................................................................................
} 

# Test malloc failure whilst installing a foreign key.
#
do_malloc_test 21 -sqlbody {
  CREATE TABLE abc(a, b, c, FOREIGN KEY(a) REFERENCES abc(b))
} 


















# Ensure that no file descriptors were leaked.
do_test malloc-99.X {
  catch {db close}
  set sqlite_open_file_count
} {0}

puts open-file-count=$sqlite_open_file_count
sqlite_malloc_fail 0
finish_test







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
#***********************************************************************
# 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.41 2007/04/19 11:09:02 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]==""} {
................................................................................
} 

# Test malloc failure whilst installing a foreign key.
#
do_malloc_test 21 -sqlbody {
  CREATE TABLE abc(a, b, c, FOREIGN KEY(a) REFERENCES abc(b))
} 

# Test malloc failure in an sqlite3_prepare_v2() call.
#
do_malloc_test 22 -tclbody {
  set ::STMT ""
  set r [catch {
    set ::STMT [
      sqlite3_prepare_v2 $::DB "SELECT * FROM sqlite_master" -1 DUMMY
    ]
  } msg]
  if {$r} {error [string range $msg 4 end]}
} -cleanup {
  if {$::STMT ne ""} {
    sqlite3_finalize $::STMT
    set ::STMT ""
  }
}

# Ensure that no file descriptors were leaked.
do_test malloc-99.X {
  catch {db close}
  set sqlite_open_file_count
} {0}

puts open-file-count=$sqlite_open_file_count
sqlite_malloc_fail 0
finish_test

Changes to test/vtab_err.test.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#
#    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.
#
#***********************************************************************
#
# $Id: vtab_err.test,v 1.4 2007/01/02 18:41:58 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]==""} {
................................................................................
  COMMIT;
  BEGIN;
    CREATE TABLE r2(a, b, c);
    INSERT INTO r2 SELECT * FROM e;
    INSERT INTO e SELECT a||'x', b, c FROM r2;
  COMMIT;
}


do_malloc_test vtab_err-2 -tclprep {
  register_echo_module [sqlite3_connection_pointer db]
} -sqlbody {
  BEGIN;
  CREATE TABLE r(a PRIMARY KEY, b, c);
  CREATE VIRTUAL TABLE e USING echo(r);







|







 







<







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
141
142
143
144
145
146
147

148
149
150
151
152
153
154
#
#    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.
#
#***********************************************************************
#
# $Id: vtab_err.test,v 1.5 2007/04/19 11:09:02 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]==""} {
................................................................................
  COMMIT;
  BEGIN;
    CREATE TABLE r2(a, b, c);
    INSERT INTO r2 SELECT * FROM e;
    INSERT INTO e SELECT a||'x', b, c FROM r2;
  COMMIT;
}


do_malloc_test vtab_err-2 -tclprep {
  register_echo_module [sqlite3_connection_pointer db]
} -sqlbody {
  BEGIN;
  CREATE TABLE r(a PRIMARY KEY, b, c);
  CREATE VIRTUAL TABLE e USING echo(r);