diff options
author | dan <dan@noemail.net> | 2016-11-11 18:45:55 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2016-11-11 18:45:55 +0000 |
commit | 04cd7aa373d0218a766aa24987a99d16bcdcbac2 (patch) | |
tree | f44e1af007c5bd8eb814cac3bec1bea0476ec781 /test | |
parent | 9af90b7231660b5c5670e41ad58c755d95d0fbaa (diff) | |
parent | 4a5bad572ae669f2c6da3299303840bf3852d5b3 (diff) | |
download | sqlite-04cd7aa373d0218a766aa24987a99d16bcdcbac2.tar.gz sqlite-04cd7aa373d0218a766aa24987a99d16bcdcbac2.zip |
Merge trunk with this branch.
FossilOrigin-Name: dd62d2de6eb12dc1902d6df050c395b1dcac01b4
Diffstat (limited to 'test')
-rw-r--r-- | test/bestindex4.test | 121 | ||||
-rw-r--r-- | test/fuzz-oss1.test | 4 | ||||
-rw-r--r-- | test/fuzzcheck.c | 53 | ||||
-rw-r--r-- | test/nockpt.test | 6 | ||||
-rw-r--r-- | test/ossfuzz.c | 80 | ||||
-rw-r--r-- | test/rowvalue.test | 13 | ||||
-rw-r--r-- | test/shell3.test | 2 |
7 files changed, 261 insertions, 18 deletions
diff --git a/test/bestindex4.test b/test/bestindex4.test new file mode 100644 index 000000000..836701f6b --- /dev/null +++ b/test/bestindex4.test @@ -0,0 +1,121 @@ +# 2016 November 11 +# +# 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. +# +#*********************************************************************** +# Test the virtual table interface. In particular the xBestIndex +# method. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix bestindex4 + +ifcapable !vtab { + finish_test + return +} + +#------------------------------------------------------------------------- +# Virtual table callback for a virtual table named $tbl. +# +# The table created is: +# +# "CREATE TABLE t1 (id, host, class)" +# +# The virtual table supports == operators on a subset of its columns. The +# exact subset depends on the value of bitmask paramater $param. +# +# 0x01 - == on "id" supported +# 0x02 - == on "host" supported +# 0x04 - == on "class" supported +# +# $param also supports the following bits: +# +# 0x08 - ignore the "usable" flag (malfunction) +# +# +# +proc vtab_cmd {param method args} { + switch -- $method { + xConnect { + return "CREATE TABLE t1(id TEXT, host TEXT, class TEXT)" + } + + xBestIndex { + foreach {clist orderby mask} $args {} + + set ret [list] + + set use use + + + for {set i 0} {$i < [llength $clist]} {incr i} { + array unset C + array set C [lindex $clist $i] + if { ($C(usable) || ($param & 0x08)) + && $C(op)=="eq" && ($param & 1<<$C(column)) + } { + lappend ret $use $i + break + } + } + + set score 1000000 + if {$ret!=""} { + set score [expr $score / [llength $ret]] + } + lappend ret cost $score rows $score + + return $ret + } + + xFilter { + } + } + return "" +} + +register_tcl_module db + +for {set param1 0} {$param1<16} {incr param1} { + for {set param2 0} {$param2<16} {incr param2} { + reset_db + register_tcl_module db + do_execsql_test 1.$param1.$param2.1 " + CREATE VIRTUAL TABLE t1 USING tcl('vtab_cmd $param1'); + CREATE VIRTUAL TABLE t2 USING tcl('vtab_cmd $param2'); + " + + foreach {tn sql} { + 2 "select t1.id as ID from t1, t2 where t1.id=t2.host and t2.class='xx'" + 3 { + select t1.id as ID from t1, t2 where t2.class ='xx' and t2.id = t1.host + } + 4 { + select t1.id as ID from t1, t2 where t1.host = t2.id and t2. class ='xx' + } + } { + + if {($param1 & 0x08)==0 && ($param2 & 0x08)==0} { + + do_execsql_test 1.$param1.$param2.$tn.a $sql {} + + } else { + do_test 1.$param1.$param2.$tn.b { + catchsql $sql + set {} {} + } {} + } + } + + } +} + +finish_test + diff --git a/test/fuzz-oss1.test b/test/fuzz-oss1.test index 08bc67084..e77b7ed0f 100644 --- a/test/fuzz-oss1.test +++ b/test/fuzz-oss1.test @@ -1997,5 +1997,9 @@ NULL AND ("9_u" COLLATE NOCASE = ? COLLATE NOCASE))) FROM (SELECT } } {/.* Goto .*/} +# Crash reported by OSS-FUZZ on 2016-11-10 +do_catchsql_test fuzz-oss1-detach { + DETACH x IS #1; +} {1 {near "#1": syntax error}} finish_test diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index fec65881c..442bcc6e4 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -80,6 +80,11 @@ # include <unistd.h> #endif +#ifdef SQLITE_OSS_FUZZ +# include <stddef.h> +# include <stdint.h> +#endif + /* ** Files in the virtual file system. */ @@ -794,6 +799,7 @@ static void showHelp(void){ " --load-db ARGS... Load template databases from files into SOURCE_DB\n" " -m TEXT Add a description to the database\n" " --native-vfs Use the native VFS for initially empty database files\n" +" --oss-fuzz Enable OSS-FUZZ testing\n" " --rebuild Rebuild and vacuum the database file\n" " --result-trace Show the results of each SQL command\n" " --sqlid N Use only SQL where sqlid=N\n" @@ -835,6 +841,7 @@ int main(int argc, char **argv){ char *zExpDb = 0; /* Write Databases to files in this directory */ char *zExpSql = 0; /* Write SQL to files in this directory */ void *pHeap = 0; /* Heap for use by SQLite */ + int ossFuzz = 0; /* enable OSS-FUZZ testing */ iBegin = timeOfDay(); #ifdef __unix__ @@ -895,6 +902,9 @@ int main(int argc, char **argv){ if( strcmp(z,"native-vfs")==0 ){ nativeFlag = 1; }else + if( strcmp(z,"oss-fuzz")==0 ){ + ossFuzz = 1; + }else if( strcmp(z,"quiet")==0 || strcmp(z,"q")==0 ){ quietFlag = 1; verboseFlag = 0; @@ -1123,25 +1133,34 @@ int main(int argc, char **argv){ } } createVFile("main.db", pDb->sz, pDb->a); - openFlags = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE; - if( nativeFlag && pDb->sz==0 ){ - openFlags |= SQLITE_OPEN_MEMORY; - zVfs = 0; - } - rc = sqlite3_open_v2("main.db", &db, openFlags, zVfs); - if( rc ) fatalError("cannot open inmem database"); - if( cellSzCkFlag ) runSql(db, "PRAGMA cell_size_check=ON", runFlags); - setAlarm(iTimeout); + if( ossFuzz ){ +#ifndef SQLITE_OSS_FUZZ + fatalError("--oss-fuzz not supported: recompile with -DSQLITE_OSS_FUZZ"); +#else + extern int LLVMFuzzerTestOneInput(const uint8_t*, size_t); + LLVMFuzzerTestOneInput((const uint8_t*)pSql->a, (size_t)pSql->sz); +#endif + }else{ + openFlags = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE; + if( nativeFlag && pDb->sz==0 ){ + openFlags |= SQLITE_OPEN_MEMORY; + zVfs = 0; + } + rc = sqlite3_open_v2("main.db", &db, openFlags, zVfs); + if( rc ) fatalError("cannot open inmem database"); + if( cellSzCkFlag ) runSql(db, "PRAGMA cell_size_check=ON", runFlags); + setAlarm(iTimeout); #ifndef SQLITE_OMIT_PROGRESS_CALLBACK - if( sqlFuzz || vdbeLimitFlag ){ - sqlite3_progress_handler(db, 100000, progressHandler, &vdbeLimitFlag); - } + if( sqlFuzz || vdbeLimitFlag ){ + sqlite3_progress_handler(db, 100000, progressHandler, &vdbeLimitFlag); + } #endif - do{ - runSql(db, (char*)pSql->a, runFlags); - }while( timeoutTest ); - setAlarm(0); - sqlite3_close(db); + do{ + runSql(db, (char*)pSql->a, runFlags); + }while( timeoutTest ); + setAlarm(0); + sqlite3_close(db); + } if( sqlite3_memory_used()>0 ) fatalError("memory leak"); reformatVfs(); nTest++; diff --git a/test/nockpt.test b/test/nockpt.test index f24fcaa98..cf350c3e1 100644 --- a/test/nockpt.test +++ b/test/nockpt.test @@ -51,5 +51,11 @@ do_execsql_test 1.12 { SELECT * FROM c1 } {1 2 3 4 5 6 7 8 9} +do_execsql_test 1.13 { PRAGMA main.journal_mode } {wal} +do_test 1.14 { sqlite3_db_config db NO_CKPT_ON_CLOSE 1 } {1} +do_execsql_test 1.14 { PRAGMA main.journal_mode = delete } {delete} +do_test 1.15 { file exists test.db-wal } {0} + + finish_test diff --git a/test/ossfuzz.c b/test/ossfuzz.c new file mode 100644 index 000000000..ae07bebc3 --- /dev/null +++ b/test/ossfuzz.c @@ -0,0 +1,80 @@ +/* +** This module interfaces SQLite to the Google OSS-Fuzz, fuzzer as a service. +** (https://github.com/google/oss-fuzz) +*/ +#include <stddef.h> +#include <stdint.h> +#include "sqlite3.h" + +/* +** Progress handler callback +*/ +static int progress_handler(void *pReturn) { + return *(int*)pReturn; +} + +/* +** Callback for sqlite3_exec(). +*/ +static int exec_handler(void *pCnt, int argc, char **argv, char **namev){ + int i; + for(i=0; i<argc; i++) sqlite3_free(sqlite3_mprintf("%s", argv[i])); + return ((*(int*)pCnt)--)<=0; +} + +/* +** Main entry point. The fuzzer invokes this function with each +** fuzzed input. +*/ +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + int progressArg = 0; /* 1 causes progress handler abort */ + int execCnt = 0; /* Abort row callback when count reaches zero */ + char *zErrMsg = 0; /* Error message returned by sqlite_exec() */ + sqlite3 *db; /* The database connection */ + uint8_t uSelector; /* First byte of input data[] */ + int rc; /* Return code from various interfaces */ + char *zSql; /* Zero-terminated copy of data[] */ + + if( size<3 ) return 0; /* Early out if unsufficient data */ + + /* Extract the selector byte from the beginning of the input. But only + ** do this if the second byte is a \n. If the second byte is not \n, + ** then use a default selector */ + if( data[1]=='\n' ){ + uSelector = data[0]; data += 2; size -= 2; + }else{ + uSelector = 0xfd; + } + + /* Open the database connection. Only use an in-memory database. */ + rc = sqlite3_open_v2("fuzz.db", &db, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY, 0); + if( rc ) return 0; + + /* Bit 0 of the selector enables progress callbacks. Bit 1 is the + ** return code from progress callbacks */ + if( uSelector & 1 ){ + sqlite3_progress_handler(db, 4, progress_handler, (void*)&progressArg); + } + uSelector >>= 1; + progressArg = uSelector & 1; uSelector >>= 1; + + /* Bit 2 of the selector enables foreign key constraints */ + sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_FKEY, uSelector&1, &rc); + uSelector >>= 1; + + /* Remaining bits of the selector determine a limit on the number of + ** output rows */ + execCnt = uSelector + 1; + + /* Run the SQL. The sqlite_exec() interface expects a zero-terminated + ** string, so make a copy. */ + zSql = sqlite3_mprintf("%.*s", (int)size, data); + sqlite3_exec(db, zSql, exec_handler, (void*)&execCnt, &zErrMsg); + + /* Cleanup and return */ + sqlite3_free(zErrMsg); + sqlite3_free(zSql); + sqlite3_close(db); + return 0; +} diff --git a/test/rowvalue.test b/test/rowvalue.test index 6ab1154b5..231565a4b 100644 --- a/test/rowvalue.test +++ b/test/rowvalue.test @@ -266,4 +266,17 @@ do_execsql_test 12.1 { SELECT *,'x' FROM t1 LEFT JOIN t2 ON (a,b)=(x,y); } {1 2 {} {} x} + +foreach {tn sql} { + 0 "SELECT (1,2) AS x WHERE x=3" + 1 "SELECT (1,2) BETWEEN 1 AND 2" + 2 "SELECT 1 BETWEEN (1,2) AND 2" + 3 "SELECT 2 BETWEEN 1 AND (1,2)" + 4 "SELECT (1,2) FROM (SELECT 1) ORDER BY 1" + 5 "SELECT (1,2) FROM (SELECT 1) GROUP BY 1" +} { + do_catchsql_test 13.$tn $sql {1 {row value misused}} +} + + finish_test diff --git a/test/shell3.test b/test/shell3.test index 6e38021d0..bb2524c1c 100644 --- a/test/shell3.test +++ b/test/shell3.test @@ -96,6 +96,6 @@ do_test shell3-2.6 { } {0 {}} do_test shell3-2.7 { catchcmd "foo.db" "CREATE TABLE" -} {1 {Error: incomplete SQL: CREATE TABLE}} +} {1 {Error: near line 1: near "TABLE": syntax error}} finish_test |