aboutsummaryrefslogtreecommitdiff
path: root/contrib/sqlite3/tea
diff options
context:
space:
mode:
authorCy Schubert <cy@FreeBSD.org>2019-05-05 04:14:17 +0000
committerCy Schubert <cy@FreeBSD.org>2019-05-05 04:14:17 +0000
commit02273ca83275dac07cbf662ef1d4554affd71cce (patch)
tree44d051b459016ef4f62772d755269497f4130e48 /contrib/sqlite3/tea
parent665919aaaf436bfc662701f0b0efa4488ea1b1a2 (diff)
parent32335203e048c5a74f8ff23d49527fd0440fb79b (diff)
MFV r347136:
Update sqlite3-3.27.2 (3270200) --> sqlite3-3.28.0 (3280000) MFC after: 3 days Security: CVE-2019-9937, CVE-2019-9936
Notes
Notes: svn path=/head/; revision=347139
Diffstat (limited to 'contrib/sqlite3/tea')
-rwxr-xr-xcontrib/sqlite3/tea/configure18
-rw-r--r--contrib/sqlite3/tea/configure.ac2
-rw-r--r--contrib/sqlite3/tea/generic/tclsqlite3.c225
3 files changed, 184 insertions, 61 deletions
diff --git a/contrib/sqlite3/tea/configure b/contrib/sqlite3/tea/configure
index 6244893a6794..6f3335392b0d 100755
--- a/contrib/sqlite3/tea/configure
+++ b/contrib/sqlite3/tea/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for sqlite 3.27.2.
+# Generated by GNU Autoconf 2.69 for sqlite 3.28.0.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -577,8 +577,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite'
-PACKAGE_VERSION='3.27.2'
-PACKAGE_STRING='sqlite 3.27.2'
+PACKAGE_VERSION='3.28.0'
+PACKAGE_STRING='sqlite 3.28.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -1303,7 +1303,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures sqlite 3.27.2 to adapt to many kinds of systems.
+\`configure' configures sqlite 3.28.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1365,7 +1365,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of sqlite 3.27.2:";;
+ short | recursive ) echo "Configuration of sqlite 3.28.0:";;
esac
cat <<\_ACEOF
@@ -1467,7 +1467,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-sqlite configure 3.27.2
+sqlite configure 3.28.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1878,7 +1878,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by sqlite $as_me 3.27.2, which was
+It was created by sqlite $as_me 3.28.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -9373,7 +9373,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by sqlite $as_me 3.27.2, which was
+This file was extended by sqlite $as_me 3.28.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -9426,7 +9426,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-sqlite config.status 3.27.2
+sqlite config.status 3.28.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/contrib/sqlite3/tea/configure.ac b/contrib/sqlite3/tea/configure.ac
index 10152394031d..03f9ec8007d3 100644
--- a/contrib/sqlite3/tea/configure.ac
+++ b/contrib/sqlite3/tea/configure.ac
@@ -19,7 +19,7 @@ dnl to configure the system for the local environment.
# so you can encode the package version directly into the source files.
#-----------------------------------------------------------------------
-AC_INIT([sqlite], [3.27.2])
+AC_INIT([sqlite], [3.28.0])
#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
diff --git a/contrib/sqlite3/tea/generic/tclsqlite3.c b/contrib/sqlite3/tea/generic/tclsqlite3.c
index 7fe86d6848c5..88b4abf485cb 100644
--- a/contrib/sqlite3/tea/generic/tclsqlite3.c
+++ b/contrib/sqlite3/tea/generic/tclsqlite3.c
@@ -98,6 +98,14 @@ typedef struct SqliteDb SqliteDb;
/*
** New SQL functions can be created as TCL scripts. Each such function
** is described by an instance of the following structure.
+**
+** Variable eType may be set to SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT,
+** SQLITE_BLOB or SQLITE_NULL. If it is SQLITE_NULL, then the implementation
+** attempts to determine the type of the result based on the Tcl object.
+** If it is SQLITE_TEXT or SQLITE_BLOB, then a text (sqlite3_result_text())
+** or blob (sqlite3_result_blob()) is returned. If it is SQLITE_INTEGER
+** or SQLITE_FLOAT, then an attempt is made to return an integer or float
+** value, falling back to float and then text if this is not possible.
*/
typedef struct SqlFunc SqlFunc;
struct SqlFunc {
@@ -105,6 +113,7 @@ struct SqlFunc {
Tcl_Obj *pScript; /* The Tcl_Obj representation of the script */
SqliteDb *pDb; /* Database connection that owns this function */
int useEvalObjv; /* True if it is safe to use Tcl_EvalObjv */
+ int eType; /* Type of value to return */
char *zName; /* Name of this function */
SqlFunc *pNext; /* Next function on the list of them all */
};
@@ -155,6 +164,7 @@ struct SqliteDb {
char *zTraceV2; /* The trace_v2 callback routine */
char *zProfile; /* The profile callback routine */
char *zProgress; /* The progress callback routine */
+ char *zBindFallback; /* Callback to invoke on a binding miss */
char *zAuth; /* The authorization callback routine */
int disableAuth; /* Disable the authorizer if it exists */
char *zNull; /* Text to substitute for an SQL NULL value */
@@ -545,6 +555,9 @@ static void SQLITE_TCLAPI DbDeleteCmd(void *db){
if( pDb->zProfile ){
Tcl_Free(pDb->zProfile);
}
+ if( pDb->zBindFallback ){
+ Tcl_Free(pDb->zBindFallback);
+ }
if( pDb->zAuth ){
Tcl_Free(pDb->zAuth);
}
@@ -1000,27 +1013,54 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
u8 *data;
const char *zType = (pVar->typePtr ? pVar->typePtr->name : "");
char c = zType[0];
- if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){
- /* Only return a BLOB type if the Tcl variable is a bytearray and
- ** has no string representation. */
- data = Tcl_GetByteArrayFromObj(pVar, &n);
- sqlite3_result_blob(context, data, n, SQLITE_TRANSIENT);
- }else if( c=='b' && strcmp(zType,"boolean")==0 ){
- Tcl_GetIntFromObj(0, pVar, &n);
- sqlite3_result_int(context, n);
- }else if( c=='d' && strcmp(zType,"double")==0 ){
- double r;
- Tcl_GetDoubleFromObj(0, pVar, &r);
- sqlite3_result_double(context, r);
- }else if( (c=='w' && strcmp(zType,"wideInt")==0) ||
- (c=='i' && strcmp(zType,"int")==0) ){
- Tcl_WideInt v;
- Tcl_GetWideIntFromObj(0, pVar, &v);
- sqlite3_result_int64(context, v);
- }else{
- data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
- sqlite3_result_text(context, (char *)data, n, SQLITE_TRANSIENT);
+ int eType = p->eType;
+
+ if( eType==SQLITE_NULL ){
+ if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){
+ /* Only return a BLOB type if the Tcl variable is a bytearray and
+ ** has no string representation. */
+ eType = SQLITE_BLOB;
+ }else if( (c=='b' && strcmp(zType,"boolean")==0)
+ || (c=='w' && strcmp(zType,"wideInt")==0)
+ || (c=='i' && strcmp(zType,"int")==0)
+ ){
+ eType = SQLITE_INTEGER;
+ }else if( c=='d' && strcmp(zType,"double")==0 ){
+ eType = SQLITE_FLOAT;
+ }else{
+ eType = SQLITE_TEXT;
+ }
}
+
+ switch( eType ){
+ case SQLITE_BLOB: {
+ data = Tcl_GetByteArrayFromObj(pVar, &n);
+ sqlite3_result_blob(context, data, n, SQLITE_TRANSIENT);
+ break;
+ }
+ case SQLITE_INTEGER: {
+ Tcl_WideInt v;
+ if( TCL_OK==Tcl_GetWideIntFromObj(0, pVar, &v) ){
+ sqlite3_result_int64(context, v);
+ break;
+ }
+ /* fall-through */
+ }
+ case SQLITE_FLOAT: {
+ double r;
+ if( TCL_OK==Tcl_GetDoubleFromObj(0, pVar, &r) ){
+ sqlite3_result_double(context, r);
+ break;
+ }
+ /* fall-through */
+ }
+ default: {
+ data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
+ sqlite3_result_text(context, (char *)data, n, SQLITE_TRANSIENT);
+ break;
+ }
+ }
+
}
}
@@ -1270,6 +1310,8 @@ static int dbPrepareAndBind(
int iParm = 0; /* Next free entry in apParm */
char c;
int i;
+ int needResultReset = 0; /* Need to invoke Tcl_ResetResult() */
+ int rc = SQLITE_OK; /* Value to return */
Tcl_Interp *interp = pDb->interp;
*ppPreStmt = 0;
@@ -1357,6 +1399,25 @@ static int dbPrepareAndBind(
const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':' || zVar[0]=='@') ){
Tcl_Obj *pVar = Tcl_GetVar2Ex(interp, &zVar[1], 0, 0);
+ if( pVar==0 && pDb->zBindFallback!=0 ){
+ Tcl_Obj *pCmd;
+ int rx;
+ pCmd = Tcl_NewStringObj(pDb->zBindFallback, -1);
+ Tcl_IncrRefCount(pCmd);
+ Tcl_ListObjAppendElement(interp, pCmd, Tcl_NewStringObj(zVar,-1));
+ if( needResultReset ) Tcl_ResetResult(interp);
+ needResultReset = 1;
+ rx = Tcl_EvalObjEx(interp, pCmd, TCL_EVAL_DIRECT);
+ Tcl_DecrRefCount(pCmd);
+ if( rx==TCL_OK ){
+ pVar = Tcl_GetObjResult(interp);
+ }else if( rx==TCL_ERROR ){
+ rc = TCL_ERROR;
+ break;
+ }else{
+ pVar = 0;
+ }
+ }
if( pVar ){
int n;
u8 *data;
@@ -1392,12 +1453,14 @@ static int dbPrepareAndBind(
}else{
sqlite3_bind_null(pStmt, i);
}
+ if( needResultReset ) Tcl_ResetResult(pDb->interp);
}
}
pPreStmt->nParm = iParm;
*ppPreStmt = pPreStmt;
+ if( needResultReset && rc==TCL_OK ) Tcl_ResetResult(pDb->interp);
- return TCL_OK;
+ return rc;
}
/*
@@ -1856,35 +1919,36 @@ static int SQLITE_TCLAPI DbObjCmd(
int choice;
int rc = TCL_OK;
static const char *DB_strs[] = {
- "authorizer", "backup", "busy",
- "cache", "changes", "close",
- "collate", "collation_needed", "commit_hook",
- "complete", "copy", "deserialize",
- "enable_load_extension", "errorcode", "eval",
- "exists", "function", "incrblob",
- "interrupt", "last_insert_rowid", "nullvalue",
- "onecolumn", "preupdate", "profile",
- "progress", "rekey", "restore",
- "rollback_hook", "serialize", "status",
- "timeout", "total_changes", "trace",
- "trace_v2", "transaction", "unlock_notify",
- "update_hook", "version", "wal_hook",
- 0
+ "authorizer", "backup", "bind_fallback",
+ "busy", "cache", "changes",
+ "close", "collate", "collation_needed",
+ "commit_hook", "complete", "copy",
+ "deserialize", "enable_load_extension", "errorcode",
+ "eval", "exists", "function",
+ "incrblob", "interrupt", "last_insert_rowid",
+ "nullvalue", "onecolumn", "preupdate",
+ "profile", "progress", "rekey",
+ "restore", "rollback_hook", "serialize",
+ "status", "timeout", "total_changes",
+ "trace", "trace_v2", "transaction",
+ "unlock_notify", "update_hook", "version",
+ "wal_hook", 0
};
enum DB_enum {
- DB_AUTHORIZER, DB_BACKUP, DB_BUSY,
- DB_CACHE, DB_CHANGES, DB_CLOSE,
- DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK,
- DB_COMPLETE, DB_COPY, DB_DESERIALIZE,
- DB_ENABLE_LOAD_EXTENSION, DB_ERRORCODE, DB_EVAL,
- DB_EXISTS, DB_FUNCTION, DB_INCRBLOB,
- DB_INTERRUPT, DB_LAST_INSERT_ROWID, DB_NULLVALUE,
- DB_ONECOLUMN, DB_PREUPDATE, DB_PROFILE,
- DB_PROGRESS, DB_REKEY, DB_RESTORE,
- DB_ROLLBACK_HOOK, DB_SERIALIZE, DB_STATUS,
- DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE,
- DB_TRACE_V2, DB_TRANSACTION, DB_UNLOCK_NOTIFY,
- DB_UPDATE_HOOK, DB_VERSION, DB_WAL_HOOK
+ DB_AUTHORIZER, DB_BACKUP, DB_BIND_FALLBACK,
+ DB_BUSY, DB_CACHE, DB_CHANGES,
+ DB_CLOSE, DB_COLLATE, DB_COLLATION_NEEDED,
+ DB_COMMIT_HOOK, DB_COMPLETE, DB_COPY,
+ DB_DESERIALIZE, DB_ENABLE_LOAD_EXTENSION,DB_ERRORCODE,
+ DB_EVAL, DB_EXISTS, DB_FUNCTION,
+ DB_INCRBLOB, DB_INTERRUPT, DB_LAST_INSERT_ROWID,
+ DB_NULLVALUE, DB_ONECOLUMN, DB_PREUPDATE,
+ DB_PROFILE, DB_PROGRESS, DB_REKEY,
+ DB_RESTORE, DB_ROLLBACK_HOOK, DB_SERIALIZE,
+ DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES,
+ DB_TRACE, DB_TRACE_V2, DB_TRANSACTION,
+ DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, DB_VERSION,
+ DB_WAL_HOOK
};
/* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
@@ -2006,6 +2070,49 @@ static int SQLITE_TCLAPI DbObjCmd(
break;
}
+ /* $db bind_fallback ?CALLBACK?
+ **
+ ** When resolving bind parameters in an SQL statement, if the parameter
+ ** cannot be associated with a TCL variable then invoke CALLBACK with a
+ ** single argument that is the name of the parameter and use the return
+ ** value of the CALLBACK as the binding. If CALLBACK returns something
+ ** other than TCL_OK or TCL_ERROR then bind a NULL.
+ **
+ ** If CALLBACK is an empty string, then revert to the default behavior
+ ** which is to set the binding to NULL.
+ **
+ ** If CALLBACK returns an error, that causes the statement execution to
+ ** abort. Hence, to configure a connection so that it throws an error
+ ** on an attempt to bind an unknown variable, do something like this:
+ **
+ ** proc bind_error {name} {error "no such variable: $name"}
+ ** db bind_fallback bind_error
+ */
+ case DB_BIND_FALLBACK: {
+ if( objc>3 ){
+ Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
+ return TCL_ERROR;
+ }else if( objc==2 ){
+ if( pDb->zBindFallback ){
+ Tcl_AppendResult(interp, pDb->zBindFallback, (char*)0);
+ }
+ }else{
+ char *zCallback;
+ int len;
+ if( pDb->zBindFallback ){
+ Tcl_Free(pDb->zBindFallback);
+ }
+ zCallback = Tcl_GetStringFromObj(objv[2], &len);
+ if( zCallback && len>0 ){
+ pDb->zBindFallback = Tcl_Alloc( len + 1 );
+ memcpy(pDb->zBindFallback, zCallback, len+1);
+ }else{
+ pDb->zBindFallback = 0;
+ }
+ }
+ break;
+ }
+
/* $db busy ?CALLBACK?
**
** Invoke the given callback if an SQL statement attempts to open
@@ -2651,6 +2758,7 @@ deserialize_error:
char *zName;
int nArg = -1;
int i;
+ int eType = SQLITE_NULL;
if( objc<4 ){
Tcl_WrongNumArgs(interp, 2, objv, "NAME ?SWITCHES? SCRIPT");
return TCL_ERROR;
@@ -2658,7 +2766,7 @@ deserialize_error:
for(i=3; i<(objc-1); i++){
const char *z = Tcl_GetString(objv[i]);
int n = strlen30(z);
- if( n>2 && strncmp(z, "-argcount",n)==0 ){
+ if( n>1 && strncmp(z, "-argcount",n)==0 ){
if( i==(objc-2) ){
Tcl_AppendResult(interp, "option requires an argument: ", z,(char*)0);
return TCL_ERROR;
@@ -2671,11 +2779,25 @@ deserialize_error:
}
i++;
}else
- if( n>2 && strncmp(z, "-deterministic",n)==0 ){
+ if( n>1 && strncmp(z, "-deterministic",n)==0 ){
flags |= SQLITE_DETERMINISTIC;
+ }else
+ if( n>1 && strncmp(z, "-returntype", n)==0 ){
+ const char *azType[] = {"integer", "real", "text", "blob", "any", 0};
+ assert( SQLITE_INTEGER==1 && SQLITE_FLOAT==2 && SQLITE_TEXT==3 );
+ assert( SQLITE_BLOB==4 && SQLITE_NULL==5 );
+ if( i==(objc-2) ){
+ Tcl_AppendResult(interp, "option requires an argument: ", z,(char*)0);
+ return TCL_ERROR;
+ }
+ i++;
+ if( Tcl_GetIndexFromObj(interp, objv[i], azType, "type", 0, &eType) ){
+ return TCL_ERROR;
+ }
+ eType++;
}else{
Tcl_AppendResult(interp, "bad option \"", z,
- "\": must be -argcount or -deterministic", (char*)0
+ "\": must be -argcount, -deterministic or -returntype", (char*)0
);
return TCL_ERROR;
}
@@ -2691,6 +2813,7 @@ deserialize_error:
pFunc->pScript = pScript;
Tcl_IncrRefCount(pScript);
pFunc->useEvalObjv = safeToUseEvalObjv(interp, pScript);
+ pFunc->eType = eType;
rc = sqlite3_create_function(pDb->db, zName, nArg, flags,
pFunc, tclSqlFunc, 0, 0);
if( rc!=SQLITE_OK ){