diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/alter.c | 17 | ||||
-rw-r--r-- | src/global.c | 1 | ||||
-rw-r--r-- | src/main.c | 17 | ||||
-rw-r--r-- | src/pragma.c | 1 | ||||
-rw-r--r-- | src/resolve.c | 9 | ||||
-rw-r--r-- | src/shell.c.in | 2 | ||||
-rw-r--r-- | src/sqlite.h.in | 1 | ||||
-rw-r--r-- | src/sqliteInt.h | 11 | ||||
-rw-r--r-- | src/test1.c | 17 |
9 files changed, 51 insertions, 25 deletions
diff --git a/src/alter.c b/src/alter.c index e299e6537..1280e9055 100644 --- a/src/alter.c +++ b/src/alter.c @@ -1188,15 +1188,8 @@ static void renameParseCleanup(Parse *pParse){ ** into zNew. The name should be quoted if bQuote is true. ** ** This function is used internally by the ALTER TABLE RENAME COLUMN command. -** Though accessible to application code, it is not intended for use by -** applications. The existance of this function, and the way it works, -** is subject to change without notice. -** -** If any of the parameters are out-of-bounds, then simply return NULL. -** An out-of-bounds parameter can only occur when the application calls -** this function directly. The parameters will always be well-formed when -** this routine is invoked by the bytecode for a legitimate ALTER TABLE -** statement. +** It is only accessible to SQL created using sqlite3NestedParse(). It is +** not reachable from ordinary SQL passed into sqlite3_prepare(). */ static void renameColumnFunc( sqlite3_context *context, @@ -1604,9 +1597,9 @@ static void renameTableTest( */ void sqlite3AlterFunctions(void){ static FuncDef aAlterTableFuncs[] = { - FUNCTION(sqlite_rename_column, 9, 0, 0, renameColumnFunc), - FUNCTION(sqlite_rename_table, 7, 0, 0, renameTableFunc), - FUNCTION(sqlite_rename_test, 5, 0, 0, renameTableTest), + INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc), + INTERNAL_FUNCTION(sqlite_rename_table, 7, renameTableFunc), + INTERNAL_FUNCTION(sqlite_rename_test, 5, renameTableTest), }; sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); } diff --git a/src/global.c b/src/global.c index f0362d1e0..f1a391248 100644 --- a/src/global.c +++ b/src/global.c @@ -240,6 +240,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = { 0, /* xTestCallback */ #endif 0, /* bLocaltimeFault */ + 0, /* bInternalFunctions */ 0x7ffffffe, /* iOnceResetThreshold */ SQLITE_DEFAULT_SORTERREF_SIZE /* szSorterRef */ }; diff --git a/src/main.c b/src/main.c index 1e5598393..46c83463c 100644 --- a/src/main.c +++ b/src/main.c @@ -3953,15 +3953,26 @@ int sqlite3_test_control(int op, ...){ /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff); ** - ** If parameter onoff is non-zero, configure the wrappers so that all - ** subsequent calls to localtime() and variants fail. If onoff is zero, - ** undo this setting. + ** If parameter onoff is non-zero, subsequent calls to localtime() + ** and its variants fail. If onoff is zero, undo this setting. */ case SQLITE_TESTCTRL_LOCALTIME_FAULT: { sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int); break; } + /* sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCS, int onoff); + ** + ** If parameter onoff is non-zero, internal-use-only SQL functions + ** are visible to ordinary SQL. This is useful for testing but is + ** unsafe because invalid parameters to those internal-use-only functions + ** can result in crashes or segfaults. + */ + case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: { + sqlite3GlobalConfig.bInternalFunctions = va_arg(ap, int); + break; + } + /* sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int); ** ** Set or clear a flag that indicates that the database file is always well- diff --git a/src/pragma.c b/src/pragma.c index 54e219ba6..ada652cf1 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1239,6 +1239,7 @@ void sqlite3Pragma( pParse->nMem = 2; for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){ for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash ){ + if( p->funcFlags & SQLITE_FUNC_INTERNAL ) continue; sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 1); } } diff --git a/src/resolve.c b/src/resolve.c index 34a051583..0c7dfc0b2 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -771,6 +771,15 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ notValid(pParse, pNC, "non-deterministic functions", NC_IdxExpr|NC_PartIdx); } + if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0 + && pParse->nested==0 + && sqlite3Config.bInternalFunctions==0 + ){ + /* Internal-use-only functions are disallowed unless the + ** SQL is being compiled using sqlite3NestedParse() */ + no_such_func = 1; + pDef = 0; + } } if( 0==IN_RENAME_OBJECT ){ diff --git a/src/shell.c.in b/src/shell.c.in index 45a793aa5..ad5a1498b 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -7677,6 +7677,7 @@ static int do_meta_command(char *zLine, ShellState *p){ { "byteorder", SQLITE_TESTCTRL_BYTEORDER, "" }, /*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, "" }, */ { "imposter", SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE"}, + { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "BOOLEAN" }, { "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN" }, { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN" }, { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK" }, @@ -7771,6 +7772,7 @@ static int do_meta_command(char *zLine, ShellState *p){ /* sqlite3_test_control(int, int) */ case SQLITE_TESTCTRL_ASSERT: case SQLITE_TESTCTRL_ALWAYS: + case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: if( nArg==3 ){ int opt = booleanValue(azArg[2]); rc2 = sqlite3_test_control(testctrl, opt); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index fb8753bd7..69c2b27f7 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -7242,6 +7242,7 @@ int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ +#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */ #define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19 diff --git a/src/sqliteInt.h b/src/sqliteInt.h index d0e4b7385..051aa4038 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1683,8 +1683,9 @@ struct FuncDestructor { ** single query - might change over time */ #define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */ #define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */ -#define SQLITE_FUNC_WINDOW 0x10000 /* Built-in window-only function */ -#define SQLITE_FUNC_WINDOW_SIZE 0x20000 /* Requires partition size as arg. */ +#define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */ +#define SQLITE_FUNC_WINDOW_SIZE 0x20000 /* Requires partition size as arg. */ +#define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */ /* ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are @@ -1760,10 +1761,13 @@ struct FuncDestructor { #define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \ {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \ SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xFinal,0,#zName, {0}} - #define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \ {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \ SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,xInverse,#zName, {0}} +#define INTERNAL_FUNCTION(zName, nArg, xFunc) \ + {nArg, SQLITE_FUNC_INTERNAL|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \ + 0, 0, xFunc, 0, 0, 0, #zName, {0} } + /* ** All current savepoints are stored in a linked list starting at @@ -3414,6 +3418,7 @@ struct Sqlite3Config { int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */ #endif int bLocaltimeFault; /* True to fail localtime() calls */ + int bInternalFunctions; /* Internal SQL functions are visible */ int iOnceResetThreshold; /* When to reset OP_Once counters */ u32 szSorterRef; /* Min size in bytes to use sorter-refs */ }; diff --git a/src/test1.c b/src/test1.c index 3d1910f8a..e2048cb38 100644 --- a/src/test1.c +++ b/src/test1.c @@ -6329,7 +6329,7 @@ static int SQLITE_TCLAPI reset_prng_state( /* ** tclcmd: database_may_be_corrupt ** -** Indicate that database files might be corrupt. In other words, set the normal +** Indicate that database files might be corrupt. In other words, set the normal ** state of operation. */ static int SQLITE_TCLAPI database_may_be_corrupt( @@ -6344,8 +6344,9 @@ static int SQLITE_TCLAPI database_may_be_corrupt( /* ** tclcmd: database_never_corrupt ** -** Indicate that database files are always well-formed. This enables extra assert() -** statements that test conditions that are always true for well-formed databases. +** Indicate that database files are always well-formed. This enables +** extra assert() statements that test conditions that are always true +** for well-formed databases. */ static int SQLITE_TCLAPI database_never_corrupt( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ @@ -6711,9 +6712,10 @@ static int SQLITE_TCLAPI test_test_control( const char *zName; int i; } aVerb[] = { - { "SQLITE_TESTCTRL_LOCALTIME_FAULT", SQLITE_TESTCTRL_LOCALTIME_FAULT }, - { "SQLITE_TESTCTRL_SORTER_MMAP", SQLITE_TESTCTRL_SORTER_MMAP }, - { "SQLITE_TESTCTRL_IMPOSTER", SQLITE_TESTCTRL_IMPOSTER }, + { "SQLITE_TESTCTRL_LOCALTIME_FAULT", SQLITE_TESTCTRL_LOCALTIME_FAULT }, + { "SQLITE_TESTCTRL_SORTER_MMAP", SQLITE_TESTCTRL_SORTER_MMAP }, + { "SQLITE_TESTCTRL_IMPOSTER", SQLITE_TESTCTRL_IMPOSTER }, + { "SQLITE_TESTCTRL_INTERNAL_FUNCTIONS", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS}, }; int iVerb; int iFlag; @@ -6731,6 +6733,7 @@ static int SQLITE_TCLAPI test_test_control( iFlag = aVerb[iVerb].i; switch( iFlag ){ + case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: case SQLITE_TESTCTRL_LOCALTIME_FAULT: { int val; if( objc!=3 ){ @@ -6738,7 +6741,7 @@ static int SQLITE_TCLAPI test_test_control( return TCL_ERROR; } if( Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR; - sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, val); + sqlite3_test_control(iFlag, val); break; } |