/ Check-in [23bf9f26]
Login

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

Overview
Comment:Fix the sqlite3_prepare() family of interfaces so that they zero the *ppStmt value even on an SQLITE_MISUSE return. Make it clear in the documentation that the ppStmt parameter cannot be zero. (CVS 6441)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 23bf9f266559603e37b2703715eaf8ef5af6bb17
User & Date: drh 2009-04-02 18:32:27
Context
2009-04-02
20:16
Make sure the VACUUM statement locks down the page_size and auto_vacuum modes after it runs. Otherwise, pragmas might change these settings on a populated database, resulting in problems. (CVS 6442) check-in: 85e6a474 user: drh tags: trunk
18:32
Fix the sqlite3_prepare() family of interfaces so that they zero the *ppStmt value even on an SQLITE_MISUSE return. Make it clear in the documentation that the ppStmt parameter cannot be zero. (CVS 6441) check-in: 23bf9f26 user: drh tags: trunk
18:28
Fix a problem causing the BtShared.isPending flag to be cleared to early. Also coverage improvements for btree.c. (CVS 6440) check-in: 8f142344 user: danielk1977 tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/prepare.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains the implementation of the sqlite3_prepare()
    13     13   ** interface, and routines that contribute to loading the database schema
    14     14   ** from disk.
    15     15   **
    16         -** $Id: prepare.c,v 1.115 2009/04/01 16:33:38 drh Exp $
           16  +** $Id: prepare.c,v 1.116 2009/04/02 18:32:27 drh Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   
    20     20   /*
    21     21   ** Fill the InitData structure with an error message that indicates
    22     22   ** that the database is corrupt.
    23     23   */
................................................................................
   524    524     const char **pzTail       /* OUT: End of parsed string */
   525    525   ){
   526    526     Parse sParse;
   527    527     char *zErrMsg = 0;
   528    528     int rc = SQLITE_OK;
   529    529     int i;
   530    530   
   531         -  assert( ppStmt );
   532         -  *ppStmt = 0;
   533         -  if( sqlite3SafetyOn(db) ){
   534         -    return SQLITE_MISUSE;
   535         -  }
          531  +  if( sqlite3SafetyOn(db) ) return SQLITE_MISUSE;
          532  +  assert( ppStmt && *ppStmt==0 );
   536    533     assert( !db->mallocFailed );
   537    534     assert( sqlite3_mutex_held(db->mutex) );
   538    535   
   539    536     /* Check to verify that it is possible to get a read lock on all
   540    537     ** database schemas.  The inability to get a read lock indicates that
   541    538     ** some other database connection is holding a write-lock, which in
   542    539     ** turn means that the other connection has made uncommitted changes
................................................................................
   667    664     const char *zSql,         /* UTF-8 encoded SQL statement. */
   668    665     int nBytes,               /* Length of zSql in bytes. */
   669    666     int saveSqlFlag,          /* True to copy SQL text into the sqlite3_stmt */
   670    667     sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
   671    668     const char **pzTail       /* OUT: End of parsed string */
   672    669   ){
   673    670     int rc;
          671  +  assert( ppStmt!=0 );
          672  +  *ppStmt = 0;
   674    673     if( !sqlite3SafetyCheckOk(db) ){
   675    674       return SQLITE_MISUSE;
   676    675     }
   677    676     sqlite3_mutex_enter(db->mutex);
   678    677     sqlite3BtreeEnterAll(db);
   679    678     rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, ppStmt, pzTail);
   680    679     sqlite3BtreeLeaveAll(db);
................................................................................
   769    768     ** encoded string to UTF-8, then invoking sqlite3_prepare(). The
   770    769     ** tricky bit is figuring out the pointer to return in *pzTail.
   771    770     */
   772    771     char *zSql8;
   773    772     const char *zTail8 = 0;
   774    773     int rc = SQLITE_OK;
   775    774   
          775  +  assert( ppStmt );
   776    776     *ppStmt = 0;
   777    777     if( !sqlite3SafetyCheckOk(db) ){
   778    778       return SQLITE_MISUSE;
   779    779     }
   780    780     sqlite3_mutex_enter(db->mutex);
   781    781     zSql8 = sqlite3Utf16to8(db, zSql, nBytes);
   782    782     if( zSql8 ){

Changes to src/sqlite.h.in.

    26     26   ** on how SQLite interfaces are suppose to operate.
    27     27   **
    28     28   ** The name of this file under configuration management is "sqlite.h.in".
    29     29   ** The makefile makes some minor changes to this file (such as inserting
    30     30   ** the version number) and changes its name to "sqlite3.h" as
    31     31   ** part of the build process.
    32     32   **
    33         -** @(#) $Id: sqlite.h.in,v 1.436 2009/03/20 13:15:30 drh Exp $
           33  +** @(#) $Id: sqlite.h.in,v 1.437 2009/04/02 18:32:27 drh Exp $
    34     34   */
    35     35   #ifndef _SQLITE3_H_
    36     36   #define _SQLITE3_H_
    37     37   #include <stdarg.h>     /* Needed for the definition of va_list */
    38     38   
    39     39   /*
    40     40   ** Make sure we can call this stuff from C++.
................................................................................
  2225   2225   ** CAPI3REF: Compiling An SQL Statement {H13010} <S10000>
  2226   2226   ** KEYWORDS: {SQL statement compiler}
  2227   2227   **
  2228   2228   ** To execute an SQL query, it must first be compiled into a byte-code
  2229   2229   ** program using one of these routines.
  2230   2230   **
  2231   2231   ** The first argument, "db", is a [database connection] obtained from a
  2232         -** prior call to [sqlite3_open()], [sqlite3_open_v2()] or [sqlite3_open16()].
         2232  +** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or
         2233  +** [sqlite3_open16()].  The database connection must not have been closed.
  2233   2234   **
  2234   2235   ** The second argument, "zSql", is the statement to be compiled, encoded
  2235   2236   ** as either UTF-8 or UTF-16.  The sqlite3_prepare() and sqlite3_prepare_v2()
  2236   2237   ** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2()
  2237   2238   ** use UTF-16.
  2238   2239   **
  2239   2240   ** If the nByte argument is less than zero, then zSql is read up to the
................................................................................
  2242   2243   ** zSql string ends at either the first '\000' or '\u0000' character or
  2243   2244   ** the nByte-th byte, whichever comes first. If the caller knows
  2244   2245   ** that the supplied string is nul-terminated, then there is a small
  2245   2246   ** performance advantage to be gained by passing an nByte parameter that
  2246   2247   ** is equal to the number of bytes in the input string <i>including</i>
  2247   2248   ** the nul-terminator bytes.
  2248   2249   **
  2249         -** *pzTail is made to point to the first byte past the end of the
  2250         -** first SQL statement in zSql.  These routines only compile the first
  2251         -** statement in zSql, so *pzTail is left pointing to what remains
  2252         -** uncompiled.
         2250  +** If pzTail is not NULL then *pzTail is made to point to the first byte
         2251  +** past the end of the first SQL statement in zSql.  These routines only
         2252  +** compile the first statement in zSql, so *pzTail is left pointing to
         2253  +** what remains uncompiled.
  2253   2254   **
  2254   2255   ** *ppStmt is left pointing to a compiled [prepared statement] that can be
  2255   2256   ** executed using [sqlite3_step()].  If there is an error, *ppStmt is set
  2256   2257   ** to NULL.  If the input text contains no SQL (if the input is an empty
  2257   2258   ** string or a comment) then *ppStmt is set to NULL.
  2258         -** {A13018} The calling procedure is responsible for deleting the compiled
         2259  +** The calling procedure is responsible for deleting the compiled
  2259   2260   ** SQL statement using [sqlite3_finalize()] after it has finished with it.
         2261  +** ppStmt may not be NULL.
  2260   2262   **
  2261   2263   ** On success, [SQLITE_OK] is returned, otherwise an [error code] is returned.
  2262   2264   **
  2263   2265   ** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are
  2264   2266   ** recommended for all new programs. The two older interfaces are retained
  2265   2267   ** for backwards compatibility, but their use is discouraged.
  2266   2268   ** In the "v2" interfaces, the prepared statement

Changes to src/test9.c.

    10     10   **
    11     11   *************************************************************************
    12     12   **
    13     13   ** This file contains obscure tests of the C-interface required
    14     14   ** for completeness. Test code is written in C for these cases
    15     15   ** as there is not much point in binding to Tcl.
    16     16   **
    17         -** $Id: test9.c,v 1.6 2008/07/11 13:53:55 drh Exp $
           17  +** $Id: test9.c,v 1.7 2009/04/02 18:32:27 drh Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include "tcl.h"
    21     21   #include <stdlib.h>
    22     22   #include <string.h>
    23     23   
    24     24   /*
................................................................................
   110    110     ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
   111    111     Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
   112    112     int objc,              /* Number of arguments */
   113    113     Tcl_Obj *CONST objv[]  /* Command arguments */
   114    114   ){
   115    115     const char *zErrFunction = "N/A";
   116    116     sqlite3 *db = 0;
          117  +  sqlite3_stmt *pStmt;
   117    118     int rc;
   118    119   
   119    120     if( objc!=1 ){
   120    121       Tcl_WrongNumArgs(interp, 1, objv, "");
   121    122       return TCL_ERROR;
   122    123     }
   123    124   
................................................................................
   134    135   
   135    136     rc = sqlite3_errcode(db);
   136    137     if( rc!=SQLITE_MISUSE ){
   137    138       zErrFunction = "sqlite3_errcode";
   138    139       goto error_out;
   139    140     }
   140    141   
   141         -  rc = sqlite3_prepare(db, 0, 0, 0, 0);
          142  +  pStmt = (sqlite3_stmt*)1234;
          143  +  rc = sqlite3_prepare(db, 0, 0, &pStmt, 0);
   142    144     if( rc!=SQLITE_MISUSE ){
   143    145       zErrFunction = "sqlite3_prepare";
   144    146       goto error_out;
   145    147     }
          148  +  assert( pStmt==0 ); /* Verify that pStmt is zeroed even on a MISUSE error */
   146    149   
   147         -  rc = sqlite3_prepare_v2(db, 0, 0, 0, 0);
          150  +  pStmt = (sqlite3_stmt*)1234;
          151  +  rc = sqlite3_prepare_v2(db, 0, 0, &pStmt, 0);
   148    152     if( rc!=SQLITE_MISUSE ){
   149    153       zErrFunction = "sqlite3_prepare_v2";
   150    154       goto error_out;
   151    155     }
          156  +  assert( pStmt==0 );
   152    157   
   153    158   #ifndef SQLITE_OMIT_UTF16
   154         -  rc = sqlite3_prepare16(db, 0, 0, 0, 0);
          159  +  pStmt = (sqlite3_stmt*)1234;
          160  +  rc = sqlite3_prepare16(db, 0, 0, &pStmt, 0);
   155    161     if( rc!=SQLITE_MISUSE ){
   156    162       zErrFunction = "sqlite3_prepare16";
   157    163       goto error_out;
   158    164     }
   159         -  rc = sqlite3_prepare16_v2(db, 0, 0, 0, 0);
          165  +  assert( pStmt==0 );
          166  +  pStmt = (sqlite3_stmt*)1234;
          167  +  rc = sqlite3_prepare16_v2(db, 0, 0, &pStmt, 0);
   160    168     if( rc!=SQLITE_MISUSE ){
   161    169       zErrFunction = "sqlite3_prepare16_v2";
   162    170       goto error_out;
   163    171     }
          172  +  assert( pStmt==0 );
   164    173   #endif
   165    174   
   166    175     return TCL_OK;
   167    176   
   168    177   error_out:
   169    178     Tcl_ResetResult(interp);
   170    179     Tcl_AppendResult(interp, "Error testing function: ", zErrFunction, 0);