mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-24 22:22:08 +03:00
Skeleton code for the word-fuzzer virtual table.
FossilOrigin-Name: ea3a4ee136ff6699c3099178f0efaa8bb517715f
This commit is contained in:
@ -356,6 +356,7 @@ TESTSRC = \
|
||||
$(TOP)/src/test_demovfs.c \
|
||||
$(TOP)/src/test_devsym.c \
|
||||
$(TOP)/src/test_func.c \
|
||||
$(TOP)/src/test_fuzzer.c \
|
||||
$(TOP)/src/test_hexio.c \
|
||||
$(TOP)/src/test_init.c \
|
||||
$(TOP)/src/test_intarray.c \
|
||||
|
1
main.mk
1
main.mk
@ -237,6 +237,7 @@ TESTSRC = \
|
||||
$(TOP)/src/test_demovfs.c \
|
||||
$(TOP)/src/test_devsym.c \
|
||||
$(TOP)/src/test_func.c \
|
||||
$(TOP)/src/test_fuzzer.c \
|
||||
$(TOP)/src/test_hexio.c \
|
||||
$(TOP)/src/test_init.c \
|
||||
$(TOP)/src/test_intarray.c \
|
||||
|
34
manifest
34
manifest
@ -1,7 +1,10 @@
|
||||
C Minor\schange\sto\ssqlite3Utf8Read()\sto\smake\sconsistent\swith\sREAD_UTF8()\susage\sand\savoid\simplementation\sdefined\susages\sof\s<<.\s\s\nAdded\ssome\sadditional\sUTF-8\stest\scases.
|
||||
D 2011-03-24T17:43:18.990
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA1
|
||||
|
||||
C Skeleton\scode\sfor\sthe\sword-fuzzer\svirtual\stable.
|
||||
D 2011-03-26T15:05:27.457
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f
|
||||
F Makefile.in 6c96e694f446500449f683070b906de9fce17b88
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
F Makefile.vxworks c85ec1d8597fe2f7bc225af12ac1666e21379151
|
||||
F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6
|
||||
@ -101,7 +104,7 @@ F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
|
||||
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F main.mk 54190fab7cdba523e311c274c95ea480f32abfb5
|
||||
F main.mk a767e12162f02719fa94697a6ff0c8b51bcd62a6
|
||||
F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
|
||||
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
|
||||
F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac
|
||||
@ -184,7 +187,7 @@ F src/sqliteInt.h f8f1d00a22c98fd3f2fbc94da74eeb880879f89f
|
||||
F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44
|
||||
F src/status.c 4997380fbb915426fef9e500b4872e79c99267fc
|
||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||
F src/tclsqlite.c 879bf8a23d99fc0e99d9177fe1b48896bc796d65
|
||||
F src/tclsqlite.c 44979405594d33c55ec5ef8e82533d3b4133e455
|
||||
F src/test1.c 9020310c7617234b33fd1c3064f89524db25f290
|
||||
F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31
|
||||
F src/test3.c 056093cfef69ff4227a6bdb9108564dc7f45e4bc
|
||||
@ -202,6 +205,7 @@ F src/test_config.c 62f0f8f934b1d5c7e4cd4f506ae453a1117b47d7
|
||||
F src/test_demovfs.c 0aed671636735116fc872c5b03706fd5612488b5
|
||||
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
|
||||
F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5
|
||||
F src/test_fuzzer.c b09d2f47bc3ae1485100b323479c5d785d4f6e4b
|
||||
F src/test_hexio.c 1237f000ec7a491009b1233f5c626ea71bce1ea2
|
||||
F src/test_init.c 5d624ffd0409d424cf9adbfe1f056b200270077c
|
||||
F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99
|
||||
@ -475,6 +479,7 @@ F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167
|
||||
F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5
|
||||
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
|
||||
F test/fuzz_malloc.test dd7001ac86d09c154a7dff064f4739c60e2b312c
|
||||
F test/fuzzer1.test 29120e10821e2d04887b39c6c1ae4ddcbd2bb7f6
|
||||
F test/hook.test f04c3412463f8ec117c1c704c74ca0f627ce733a
|
||||
F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4
|
||||
F test/in.test 19b642bb134308980a92249750ea4ce3f6c75c2d
|
||||
@ -916,7 +921,18 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||
P 69fe0c873d702ef1d781453ee6ac2b1fb77fce48
|
||||
R 3655844fccb71eb3fdafa07a1f475145
|
||||
U shaneh
|
||||
Z 4c379d73c236b4115e9dab5017415240
|
||||
P 7173b3929fae4e678223b0e978a2da7fa50a9005
|
||||
R 88772465d0029c6e2564e31a16d9e60f
|
||||
T *bgcolor * #b0b28e
|
||||
T *branch * word-fuzzer
|
||||
T *sym-word-fuzzer *
|
||||
T -sym-trunk *
|
||||
U drh
|
||||
Z 56aa191286824371992372fc6a5d252f
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: GnuPG v1.4.6 (GNU/Linux)
|
||||
|
||||
iD8DBQFNjgC7oxKgR168RlERAutAAJ0V6j75yMfG5zTEYnDlvPG7yBJM5ACfSqKu
|
||||
yFIOeN9GMM2kCskHQ5jGilY=
|
||||
=IVMz
|
||||
-----END PGP SIGNATURE-----
|
||||
|
@ -1 +1 @@
|
||||
7173b3929fae4e678223b0e978a2da7fa50a9005
|
||||
ea3a4ee136ff6699c3099178f0efaa8bb517715f
|
@ -3581,6 +3581,7 @@ static void init_all(Tcl_Interp *interp){
|
||||
extern int Sqlitequota_Init(Tcl_Interp*);
|
||||
extern int Sqlitemultiplex_Init(Tcl_Interp*);
|
||||
extern int SqliteSuperlock_Init(Tcl_Interp*);
|
||||
extern int Sqlitetestfuzzer_Init(Tcl_Interp*);
|
||||
|
||||
#ifdef SQLITE_ENABLE_ZIPVFS
|
||||
extern int Zipvfs_Init(Tcl_Interp*);
|
||||
@ -3618,6 +3619,7 @@ static void init_all(Tcl_Interp *interp){
|
||||
Sqlitequota_Init(interp);
|
||||
Sqlitemultiplex_Init(interp);
|
||||
SqliteSuperlock_Init(interp);
|
||||
Sqlitetestfuzzer_Init(interp);
|
||||
|
||||
Tcl_CreateObjCommand(interp,"load_testfixture_extensions",init_all_cmd,0,0);
|
||||
|
||||
|
407
src/test_fuzzer.c
Normal file
407
src/test_fuzzer.c
Normal file
@ -0,0 +1,407 @@
|
||||
/*
|
||||
** 2011 March 24
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
*************************************************************************
|
||||
**
|
||||
** Code for demonstartion virtual table that generates variations
|
||||
** on an input word at increasing edit distances from the original.
|
||||
*/
|
||||
#include "sqlite3.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
|
||||
/*
|
||||
** Forward declaration of objects used by this implementation
|
||||
*/
|
||||
typedef struct fuzzer_vtab fuzzer_vtab;
|
||||
typedef struct fuzzer_cursor fuzzer_cursor;
|
||||
typedef struct fuzzer_rule fuzzer_rule;
|
||||
typedef struct fuzzer_seen fuzzer_seen;
|
||||
typedef struct fuzzer_stem fuzzer_stem;
|
||||
|
||||
|
||||
/*
|
||||
** Each transformation rule is stored as an instance of this object.
|
||||
** All rules are kept on a linked list sorted by rCost.
|
||||
*/
|
||||
struct fuzzer_rule {
|
||||
fuzzer_rule *pNext; /* Next rule in order of increasing rCost */
|
||||
float rCost; /* Cost of this transformation */
|
||||
char *zFrom; /* Transform from */
|
||||
char zTo[4]; /* Transform to (extra space appended) */
|
||||
};
|
||||
|
||||
/*
|
||||
** When generating fuzzed words, we have to remember all previously
|
||||
** generated terms in order to suppress duplicates. Each previously
|
||||
** generated term is an instance of the following structure.
|
||||
*/
|
||||
struct fuzzer_seen {
|
||||
fuzzer_seen *pNext; /* Next with the same hash */
|
||||
char zWord[4]; /* The generated term. */
|
||||
};
|
||||
|
||||
/*
|
||||
** A stem object is used to generate variants.
|
||||
*/
|
||||
struct fuzzer_stem {
|
||||
char *zBasis; /* Word being fuzzed */
|
||||
fuzzer_rule *pRule; /* Next rule to apply */
|
||||
int n; /* Apply rule at this character offset */
|
||||
float rBaseCost; /* Base cost of getting to zBasis */
|
||||
float rCost; /* rBaseCost + cost of applying pRule at n */
|
||||
fuzzer_stem *pNext; /* Next stem in rCost order */
|
||||
};
|
||||
|
||||
/*
|
||||
** A fuzzer virtual-table object
|
||||
*/
|
||||
struct fuzzer_vtab {
|
||||
sqlite3_vtab base; /* Base class - must be first */
|
||||
char *zClassName; /* Name of this class. Default: "fuzzer" */
|
||||
fuzzer_rule *pRule; /* All active rules in this fuzzer */
|
||||
fuzzer_rule *pNewRule; /* New rules to add when last cursor expires */
|
||||
int nCursor; /* Number of active cursors */
|
||||
};
|
||||
|
||||
/* A fuzzer cursor object */
|
||||
struct fuzzer_cursor {
|
||||
sqlite3_vtab_cursor base; /* Base class - must be first */
|
||||
float rMax; /* Maximum cost of any term */
|
||||
fuzzer_stem *pStem; /* Sorted list of stems for generating new terms */
|
||||
int nSeen; /* Number of terms already generated */
|
||||
int nHash; /* Number of slots in apHash */
|
||||
fuzzer_seen **apHash; /* Hash table of previously generated terms */
|
||||
};
|
||||
|
||||
/* Methods for the fuzzer module */
|
||||
static int fuzzerConnect(
|
||||
sqlite3 *db,
|
||||
void *pAux,
|
||||
int argc, const char *const*argv,
|
||||
sqlite3_vtab **ppVtab,
|
||||
char **pzErr
|
||||
){
|
||||
fuzzer_vtab *pNew;
|
||||
char *zSql;
|
||||
int n;
|
||||
if( strcmp(argv[1],"temp")!=0 ){
|
||||
*pzErr = sqlite3_mprintf("%s virtual tables must be TEMP", argv[0]);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
n = strlen(argv[0]) + 1;
|
||||
pNew = sqlite3_malloc( sizeof(*pNew) + n );
|
||||
if( pNew==0 ) return SQLITE_NOMEM;
|
||||
pNew->zClassName = (char*)&pNew[1];
|
||||
memcpy(pNew->zClassName, argv[0], n);
|
||||
zSql = sqlite3_mprintf(
|
||||
"CREATE TABLE x(word, distance, cFrom, cTo, cost, \"%w\" HIDDEN)",
|
||||
argv[2]
|
||||
);
|
||||
sqlite3_declare_vtab(db, zSql);
|
||||
sqlite3_free(zSql);
|
||||
memset(pNew, 0, sizeof(*pNew));
|
||||
*ppVtab = &pNew->base;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
/* Note that for this virtual table, the xCreate and xConnect
|
||||
** methods are identical. */
|
||||
|
||||
static int fuzzerDisconnect(sqlite3_vtab *pVtab){
|
||||
fuzzer_vtab *p = (fuzzer_vtab*)pVtab;
|
||||
assert( p->nCursor==0 );
|
||||
do{
|
||||
while( p->pRule ){
|
||||
fuzzer_rule *pRule = p->pRule;
|
||||
p->pRule = pRule->pNext;
|
||||
sqlite3_free(pRule);
|
||||
}
|
||||
p->pRule = p->pNewRule;
|
||||
p->pNewRule = 0;
|
||||
}while( p->pRule );
|
||||
sqlite3_free(p);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
/* The xDisconnect and xDestroy methods are also the same */
|
||||
|
||||
/*
|
||||
** The two input rule lists are both sorted in order of increasing
|
||||
** cost. Merge them together into a single list, sorted by cost, and
|
||||
** return a pointer to the head of that list.
|
||||
*/
|
||||
static fuzzer_rule *fuzzerMergeRules(fuzzer_rule *pA, fuzzer_rule *pB){
|
||||
fuzzer_rule head;
|
||||
fuzzer_rule *pTail;
|
||||
|
||||
pTail = &head;
|
||||
while( pA && pB ){
|
||||
if( pA->rCost<=pB->rCost ){
|
||||
pTail->pNext = pA;
|
||||
pTail = pA;
|
||||
pA = pA->pNext;
|
||||
}else{
|
||||
pTail->pNext = pB;
|
||||
pTail = pB;
|
||||
pB = pB->pNext;
|
||||
}
|
||||
}
|
||||
if( pA==0 ){
|
||||
pTail->pNext = pB;
|
||||
}else{
|
||||
pTail->pNext = pA;
|
||||
}
|
||||
return head.pNext;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Open a new fuzzer cursor.
|
||||
*/
|
||||
static int fuzzerOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
|
||||
fuzzer_vtab *p = (fuzzer_vtab*)pVTab;
|
||||
fuzzer_cursor *pCur;
|
||||
pCur = sqlite3_malloc( sizeof(*pCur) );
|
||||
if( pCur==0 ) return SQLITE_NOMEM;
|
||||
memset(pCur, 0, sizeof(*pCur));
|
||||
*ppCursor = &pCur->base;
|
||||
if( p->nCursor==0 && p->pNewRule ){
|
||||
unsigned int i;
|
||||
fuzzer_rule *pX;
|
||||
fuzzer_rule *a[15];
|
||||
for(i=0; i<sizeof(a)/sizeof(a[0]); i++) a[i] = 0;
|
||||
while( (pX = p->pNewRule)!=0 ){
|
||||
p->pNewRule = pX->pNext;
|
||||
pX->pNext = 0;
|
||||
for(i=0; a[i] && i<sizeof(a)/sizeof(a[0])-1; i++){
|
||||
pX = fuzzerMergeRules(a[i], pX);
|
||||
a[i] = 0;
|
||||
}
|
||||
a[i] = fuzzerMergeRules(a[i], pX);
|
||||
}
|
||||
for(pX=a[0], i=1; i<sizeof(a)/sizeof(a[0]); i++){
|
||||
pX = fuzzerMergeRules(a[i], pX);
|
||||
}
|
||||
p->pRule = fuzzerMergeRules(p->pRule, pX);
|
||||
}
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Close a fuzzer cursor.
|
||||
*/
|
||||
static int fuzzerClose(sqlite3_vtab_cursor *cur){
|
||||
fuzzer_cursor *pCur = (fuzzer_cursor *)cur;
|
||||
int i;
|
||||
for(i=0; i<pCur->nHash; i++){
|
||||
fuzzer_seen *pSeen = pCur->apHash[i];
|
||||
while( pSeen ){
|
||||
fuzzer_seen *pNext = pSeen->pNext;
|
||||
sqlite3_free(pSeen);
|
||||
pSeen = pNext;
|
||||
}
|
||||
}
|
||||
sqlite3_free(pCur->apHash);
|
||||
while( pCur->pStem ){
|
||||
fuzzer_stem *pStem = pCur->pStem;
|
||||
pCur->pStem = pStem->pNext;
|
||||
sqlite3_free(pStem);
|
||||
}
|
||||
sqlite3_free(pCur);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static int fuzzerNext(sqlite3_vtab_cursor *cur){
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fuzzerFilter(
|
||||
sqlite3_vtab_cursor *pVtabCursor,
|
||||
int idxNum, const char *idxStr,
|
||||
int argc, sqlite3_value **argv
|
||||
){
|
||||
fuzzer_cursor *pCur = (fuzzer_cursor *)pVtabCursor;
|
||||
return fuzzerNext(pVtabCursor);
|
||||
}
|
||||
|
||||
static int fuzzerColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
|
||||
fuzzer_cursor *pCur = (fuzzer_cursor*)cur;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static int fuzzerRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
|
||||
*pRowid = 0;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static int fuzzerEof(sqlite3_vtab_cursor *cur){
|
||||
fuzzer_cursor *pCur = (fuzzer_cursor*)cur;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int fuzzerBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Disallow all attempts to DELETE or UPDATE. Only INSERTs are allowed.
|
||||
**
|
||||
** On an insert, the cFrom, cTo, and cost columns are used to construct
|
||||
** a new rule. All other columns are ignored. The rule is ignored
|
||||
** if cFrom and cTo are identical. A NULL value for cFrom or cTo is
|
||||
** interpreted as an empty string. The cost must be positive.
|
||||
*/
|
||||
static int fuzzerUpdate(
|
||||
sqlite3_vtab *pVTab,
|
||||
int argc,
|
||||
sqlite3_value **argv,
|
||||
sqlite_int64 *pRowid
|
||||
){
|
||||
fuzzer_vtab *p = (fuzzer_vtab*)pVTab;
|
||||
fuzzer_rule *pRule;
|
||||
const char *zFrom;
|
||||
int nFrom;
|
||||
const char *zTo;
|
||||
int nTo;
|
||||
float rCost;
|
||||
if( argc!=8 ){
|
||||
sqlite3_free(pVTab->zErrMsg);
|
||||
pVTab->zErrMsg = sqlite3_mprintf("cannot delete from a %s virtual table",
|
||||
p->zClassName);
|
||||
return SQLITE_CONSTRAINT;
|
||||
}
|
||||
if( sqlite3_value_type(argv[0])!=SQLITE_NULL ){
|
||||
sqlite3_free(pVTab->zErrMsg);
|
||||
pVTab->zErrMsg = sqlite3_mprintf("cannot update a %s virtual table",
|
||||
p->zClassName);
|
||||
return SQLITE_CONSTRAINT;
|
||||
}
|
||||
zFrom = (char*)sqlite3_value_text(argv[4]);
|
||||
if( zFrom==0 ) zFrom = "";
|
||||
zTo = (char*)sqlite3_value_text(argv[5]);
|
||||
if( zTo==0 ) zTo = "";
|
||||
if( strcmp(zFrom,zTo)==0 ){
|
||||
/* Silently ignore null transformations */
|
||||
return SQLITE_OK;
|
||||
}
|
||||
rCost = (float)sqlite3_value_double(argv[6]);
|
||||
if( rCost<=0 ){
|
||||
sqlite3_free(pVTab->zErrMsg);
|
||||
pVTab->zErrMsg = sqlite3_mprintf("cost must be positive");
|
||||
return SQLITE_CONSTRAINT;
|
||||
}
|
||||
nFrom = strlen(zFrom)+1;
|
||||
nTo = strlen(zTo)+1;
|
||||
if( nTo<4 ) nTo = 4;
|
||||
pRule = sqlite3_malloc( sizeof(*pRule) + nFrom + nTo - 4 );
|
||||
if( pRule==0 ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
pRule->zFrom = &pRule->zTo[nTo];
|
||||
memcpy(pRule->zFrom, zFrom, nFrom);
|
||||
memcpy(pRule->zTo, zTo, nTo);
|
||||
pRule->rCost = rCost;
|
||||
pRule->pNext = p->pNewRule;
|
||||
p->pNewRule = pRule;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** A virtual table module that provides read-only access to a
|
||||
** Tcl global variable namespace.
|
||||
*/
|
||||
static sqlite3_module fuzzerModule = {
|
||||
0, /* iVersion */
|
||||
fuzzerConnect,
|
||||
fuzzerConnect,
|
||||
fuzzerBestIndex,
|
||||
fuzzerDisconnect,
|
||||
fuzzerDisconnect,
|
||||
fuzzerOpen, /* xOpen - open a cursor */
|
||||
fuzzerClose, /* xClose - close a cursor */
|
||||
fuzzerFilter, /* xFilter - configure scan constraints */
|
||||
fuzzerNext, /* xNext - advance a cursor */
|
||||
fuzzerEof, /* xEof - check for end of scan */
|
||||
fuzzerColumn, /* xColumn - read data */
|
||||
fuzzerRowid, /* xRowid - read data */
|
||||
fuzzerUpdate, /* xUpdate - INSERT */
|
||||
0, /* xBegin */
|
||||
0, /* xSync */
|
||||
0, /* xCommit */
|
||||
0, /* xRollback */
|
||||
0, /* xFindMethod */
|
||||
0, /* xRename */
|
||||
};
|
||||
|
||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||
|
||||
|
||||
/*
|
||||
** Register the fuzzer virtual table
|
||||
*/
|
||||
int fuzzer_register(sqlite3 *db){
|
||||
int rc = SQLITE_OK;
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
rc = sqlite3_create_module(db, "fuzzer", &fuzzerModule, 0);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef SQLITE_TEST
|
||||
#include <tcl.h>
|
||||
/*
|
||||
** Decode a pointer to an sqlite3 object.
|
||||
*/
|
||||
extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb);
|
||||
|
||||
/*
|
||||
** Register the echo virtual table module.
|
||||
*/
|
||||
static int register_fuzzer_module(
|
||||
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
sqlite3 *db;
|
||||
if( objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "DB");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
|
||||
fuzzer_register(db);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Register commands with the TCL interpreter.
|
||||
*/
|
||||
int Sqlitetestfuzzer_Init(Tcl_Interp *interp){
|
||||
static struct {
|
||||
char *zName;
|
||||
Tcl_ObjCmdProc *xProc;
|
||||
void *clientData;
|
||||
} aObjCmd[] = {
|
||||
{ "register_fuzzer_module", register_fuzzer_module, 0 },
|
||||
};
|
||||
int i;
|
||||
for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
|
||||
Tcl_CreateObjCommand(interp, aObjCmd[i].zName,
|
||||
aObjCmd[i].xProc, aObjCmd[i].clientData, 0);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
#endif /* SQLITE_TEST */
|
41
test/fuzzer1.test
Normal file
41
test/fuzzer1.test
Normal file
@ -0,0 +1,41 @@
|
||||
# 2011 March 25
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for TCL interface to the
|
||||
# SQLite library.
|
||||
#
|
||||
# The focus of the tests is the word-fuzzer virtual table.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
ifcapable !vtab {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
register_fuzzer_module db
|
||||
do_test fuzzer1-1.0 {
|
||||
catchsql {CREATE VIRTUAL TABLE fault1 USING fuzzer;}
|
||||
} {1 {fuzzer virtual tables must be TEMP}}
|
||||
do_test fuzzer1-1.1 {
|
||||
db eval {CREATE VIRTUAL TABLE temp.f1 USING fuzzer;}
|
||||
} {}
|
||||
do_test fuzzer1-1.2 {
|
||||
db eval {
|
||||
INSERT INTO f1(cfrom, cto, cost) VALUES('e','a',0.1);
|
||||
INSERT INTO f1(cfrom, cto, cost) VALUES('a','e',0.1);
|
||||
INSERT INTO f1(cfrom, cto, cost) VALUES('e','o',0.1);
|
||||
}
|
||||
} {}
|
||||
|
||||
|
||||
finish_test
|
Reference in New Issue
Block a user