Updates to the instructions in the header comment of the fuzzer implementation.

New test cases for the fuzzer.

FossilOrigin-Name: bf1dc7907cf1a5c7e19b04fa1278b2089316c30a
This commit is contained in:
drh 2012-02-20 22:44:12 +00:00
parent a8ab692fa2
commit 5577671da3
4 changed files with 80 additions and 23 deletions

View File

@ -1,5 +1,5 @@
C Change\sthe\sway\sthe\sfuzzer\s(test_fuzzer.c)\sworks\sso\sthat\sit\sloads\sits\sconfiguration\sfrom\sa\sdatabase\stable. C Updates\sto\sthe\sinstructions\sin\sthe\sheader\scomment\sof\sthe\sfuzzer\simplementation.\nNew\stest\scases\sfor\sthe\sfuzzer.
D 2012-02-20T20:03:48.835 D 2012-02-20T22:44:12.628
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 3f79a373e57c3b92dabf76f40b065e719d31ac34 F Makefile.in 3f79a373e57c3b92dabf76f40b065e719d31ac34
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -206,7 +206,7 @@ F src/test_config.c a036a69b550ebc477ab9ca2b37269201f888436e
F src/test_demovfs.c 20a4975127993f4959890016ae9ce5535a880094 F src/test_demovfs.c 20a4975127993f4959890016ae9ce5535a880094
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
F src/test_func.c 6232d722a4ddb193035aa13a03796bf57d6c12fd F src/test_func.c 6232d722a4ddb193035aa13a03796bf57d6c12fd
F src/test_fuzzer.c 010ee3d4122fd955d6f0db598f68d62f95d15fa9 F src/test_fuzzer.c 2c0d96f94fdf7bfc2458dac9835c87b2086fdb67
F src/test_hexio.c c4773049603151704a6ab25ac5e936b5109caf5a F src/test_hexio.c c4773049603151704a6ab25ac5e936b5109caf5a
F src/test_init.c 3cbad7ce525aec925f8fda2192d576d47f0d478a F src/test_init.c 3cbad7ce525aec925f8fda2192d576d47f0d478a
F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99 F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99
@ -504,7 +504,7 @@ F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167
F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5 F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
F test/fuzzer1.test 50a480932b91df9d61dd089f338e448991ab771e F test/fuzzer1.test 830e260b10213d5dc6aadccc1fc4b0c7fefce7b8
F test/hook.test 5f3749de6462a6b87b4209b74adf7df5ac2df639 F test/hook.test 5f3749de6462a6b87b4209b74adf7df5ac2df639
F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4
F test/in.test a7b8a0f43da81cd08645b7a710099ffe9ad1126b F test/in.test a7b8a0f43da81cd08645b7a710099ffe9ad1126b
@ -989,7 +989,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
P cb5f5ebc563b8d3e47bc30b6dbb374bb91efd3ef P 90b7b957f8933047fd2878048dfa3ec4891988b8
R 15ed6cfb8d0ad7f6ea31fbc888768f7f R e208940f645a7d6e8e24937143961be4
U dan U drh
Z d7a1a4dc789683dc31afc336a51e56bf Z c02d350749266fd28db3de432a6902e8

View File

@ -1 +1 @@
90b7b957f8933047fd2878048dfa3ec4891988b8 bf1dc7907cf1a5c7e19b04fa1278b2089316c30a

View File

@ -28,13 +28,13 @@
** that consist of four columns). It does not matter what the columns are ** that consist of four columns). It does not matter what the columns are
** named. ** named.
** **
** Each row in the fuzzer table represents a single character transformation. ** Each row in the fuzzer data table represents a single character
** The left most column of the row (column 0) contains an integer value - ** transformation. The left most column of the row (column 0) contains an
** the identifier of the ruleset to which the transformation rule belongs ** integer value - the identifier of the ruleset to which the transformation
** (see "MULTIPLE RULE SETS" below). The second column of the row (column 0) ** rule belongs (see "MULTIPLE RULE SETS" below). The second column of the
** contains the input character or characters. The third column contains the ** row (column 0) contains the input character or characters. The third
** output character or characters. And the fourth column contains the integer ** column contains the output character or characters. And the fourth column
** cost of making the transformation. For example: ** contains the integer cost of making the transformation. For example:
** **
** CREATE TABLE f_data(ruleset, cFrom, cTo, Cost); ** CREATE TABLE f_data(ruleset, cFrom, cTo, Cost);
** INSERT INTO f_data(ruleset, cFrom, cTo, Cost) VALUES(0, '', 'a', 100); ** INSERT INTO f_data(ruleset, cFrom, cTo, Cost) VALUES(0, '', 'a', 100);
@ -46,9 +46,9 @@
** above indicates that the cost of inserting a letter 'a' is 100. (All ** above indicates that the cost of inserting a letter 'a' is 100. (All
** costs are integers. We recommend that costs be scaled so that the ** costs are integers. We recommend that costs be scaled so that the
** average cost is around 100.) The second INSERT statement creates a rule ** average cost is around 100.) The second INSERT statement creates a rule
** that the cost of that the cost of deleting a single letter 'b' is 87. ** saying that the cost of deleting a single letter 'b' is 87. The third
** The third and fourth INSERT statements mean that the cost of transforming ** and fourth INSERT statements mean that the cost of transforming a
** a single letter "o" into the two-letter sequence "oe" is 38 and that the ** single letter "o" into the two-letter sequence "oe" is 38 and that the
** cost of transforming "oe" back into "o" is 40. ** cost of transforming "oe" back into "o" is 40.
** **
** The contents of the fuzzer data table are loaded into main memory when ** The contents of the fuzzer data table are loaded into main memory when
@ -58,6 +58,8 @@
** If you do need to modify the contents of the fuzzer data table, it is ** If you do need to modify the contents of the fuzzer data table, it is
** recommended that the associated fuzzer table be dropped, the fuzzer data ** recommended that the associated fuzzer table be dropped, the fuzzer data
** table edited, and the fuzzer table recreated within a single transaction. ** table edited, and the fuzzer table recreated within a single transaction.
** Alternatively, the fuzzer data table can be edited then the database
** connection can be closed and reopened.
** **
** Once it has been created, the fuzzer table can be queried as follows: ** Once it has been created, the fuzzer table can be queried as follows:
** **
@ -74,6 +76,9 @@
** the one that is returned. In the example, the search is limited to ** the one that is returned. In the example, the search is limited to
** strings with a total distance of less than 200. ** strings with a total distance of less than 200.
** **
** The fuzzer is a read-only table. Any attempt to DELETE, INSERT, or
** UPDATE on a fuzzer table will throw an error.
**
** It is important to put some kind of a limit on the fuzzer output. This ** It is important to put some kind of a limit on the fuzzer output. This
** can be either in the form of a LIMIT clause at the end of the query, ** can be either in the form of a LIMIT clause at the end of the query,
** or better, a "distance<NNN" constraint where NNN is some number. The ** or better, a "distance<NNN" constraint where NNN is some number. The
@ -129,6 +134,12 @@
** **
** If no "ruleset = ?" constraint is specified in the WHERE clause, ruleset ** If no "ruleset = ?" constraint is specified in the WHERE clause, ruleset
** 0 is used. ** 0 is used.
**
** LIMITS
**
** The maximum ruleset number is 2147483647. The maximum length of either
** of the strings in the second or third column of the fuzzer data table
** is 50 bytes. The maximum cost on a rule is 1000.
*/ */
#include "sqlite3.h" #include "sqlite3.h"
#include <stdlib.h> #include <stdlib.h>
@ -777,6 +788,7 @@ static fuzzer_stem *fuzzerNewStem(
fuzzer_cost rBaseCost fuzzer_cost rBaseCost
){ ){
fuzzer_stem *pNew; fuzzer_stem *pNew;
fuzzer_rule *pRule;
unsigned int h; unsigned int h;
pNew = sqlite3_malloc( sizeof(*pNew) + strlen(zWord) + 1 ); pNew = sqlite3_malloc( sizeof(*pNew) + strlen(zWord) + 1 );
@ -785,10 +797,11 @@ static fuzzer_stem *fuzzerNewStem(
pNew->zBasis = (char*)&pNew[1]; pNew->zBasis = (char*)&pNew[1];
pNew->nBasis = strlen(zWord); pNew->nBasis = strlen(zWord);
memcpy(pNew->zBasis, zWord, pNew->nBasis+1); memcpy(pNew->zBasis, zWord, pNew->nBasis+1);
pNew->pRule = pCur->pVtab->pRule; pRule = pCur->pVtab->pRule;
while( pNew->pRule && pNew->pRule->iRuleset!=pCur->iRuleset ){ while( pRule && pRule->iRuleset!=pCur->iRuleset ){
pNew->pRule = pNew->pRule->pNext; pRule = pRule->pNext;
} }
pNew->pRule = pRule;
pNew->n = -1; pNew->n = -1;
pNew->rBaseCost = pNew->rCostX = rBaseCost; pNew->rBaseCost = pNew->rCostX = rBaseCost;
h = fuzzerHash(pNew->zBasis); h = fuzzerHash(pNew->zBasis);

View File

@ -147,11 +147,21 @@ do_test fuzzer1-1.13 {
WHERE word MATCH 'abcde' AND distance<=11 AND ruleset=1 WHERE word MATCH 'abcde' AND distance<=11 AND ruleset=1
} }
} {abcde 0 axcde 1 abcye 10 axcye 11} } {abcde 0 axcde 1 abcye 10 axcye 11}
do_test fuzzer1-1.14 {
catchsql {INSERT INTO f1 VALUES(1)}
} {1 {table f1 may not be modified}}
do_test fuzzer1-1.15 {
catchsql {DELETE FROM f1}
} {1 {table f1 may not be modified}}
do_test fuzzer1-1.16 {
catchsql {UPDATE f1 SET rowid=rowid+10000}
} {1 {table f1 may not be modified}}
do_test fuzzer1-2.0 { do_test fuzzer1-2.0 {
execsql { execsql {
-- costs based on English letter frequencies -- costs based on English letter frequencies
CREATE TEMP TABLE f2_rules(ruleset, cFrom, cTo, cost); CREATE TEMP TABLE f2_rules(ruleset DEFAULT 0, cFrom, cTo, cost);
INSERT INTO f2_rules(cFrom,cTo,cost) VALUES('a','e',24); INSERT INTO f2_rules(cFrom,cTo,cost) VALUES('a','e',24);
INSERT INTO f2_rules(cFrom,cTo,cost) VALUES('a','o',47); INSERT INTO f2_rules(cFrom,cTo,cost) VALUES('a','o',47);
INSERT INTO f2_rules(cFrom,cTo,cost) VALUES('a','u',50); INSERT INTO f2_rules(cFrom,cTo,cost) VALUES('a','u',50);
@ -220,6 +230,18 @@ do_test fuzzer1-2.0 {
INSERT INTO f2_rules(cFrom,cTo,cost) VALUES('y','',100); INSERT INTO f2_rules(cFrom,cTo,cost) VALUES('y','',100);
INSERT INTO f2_rules(cFrom,cTo,cost) VALUES('','z',120); INSERT INTO f2_rules(cFrom,cTo,cost) VALUES('','z',120);
INSERT INTO f2_rules(cFrom,cTo,cost) VALUES('z','',120); INSERT INTO f2_rules(cFrom,cTo,cost) VALUES('z','',120);
INSERT INTO f2_rules(ruleset,cFrom,cTo,cost)
SELECT 1, cFrom, cTo, 100 FROM f2_rules WHERE ruleset=0;
INSERT INTO f2_rules(ruleset,cFrom,cTo,cost)
SELECT 2, cFrom, cTo, 200-cost FROM f2_rules WHERE ruleset=0;
INSERT INTO f2_rules(ruleset,cFrom,cTo,cost)
SELECT 3, cFrom, cTo, cost FROM f2_rules WHERE ruleset=0;
INSERT INTO f2_rules(ruleset,cFrom,cTo,cost)
VALUES(3, 'mallard','duck',50),
(3, 'duck', 'mallard', 50),
(3, 'rock', 'stone', 50),
(3, 'stone', 'rock', 50);
CREATE VIRTUAL TABLE temp.f2 USING fuzzer(f2_rules); CREATE VIRTUAL TABLE temp.f2 USING fuzzer(f2_rules);
@ -1483,6 +1505,28 @@ do_test fuzzer1-2.3 {
AND streetname.n>=f2.word AND streetname.n<=(f2.word || x'F7BFBFBF') AND streetname.n>=f2.word AND streetname.n<=(f2.word || x'F7BFBFBF')
} }
} {{tyler finley} trailer taymouth steelewood tallia tallu talwyn thelema} } {{tyler finley} trailer taymouth steelewood tallia tallu talwyn thelema}
do_test fuzzer1-2.4 {
execsql {
SELECT DISTINCT streetname.n
FROM f2 JOIN streetname
ON (streetname.n>=f2.word AND streetname.n<=(f2.word || 'zzzzzz'))
WHERE f2.word MATCH 'duck'
AND f2.distance<150
AND f2.ruleset=3
ORDER BY 1
}
} {mallard {mallard cove} {mallard forest} {mallard grove} {mallard hill} {mallard park} {mallard ridge} {mallard view}}
do_test fuzzer1-2.5 {
execsql {
SELECT DISTINCT streetname.n
FROM f2 JOIN streetname
ON (streetname.n>=f2.word AND streetname.n<=(f2.word || 'zzzzzz'))
WHERE f2.word MATCH 'duck'
AND f2.distance<150
AND f2.ruleset=2
ORDER BY 1
}
} {}
forcedelete test.db2 forcedelete test.db2
do_execsql_test fuzzer1-4.1 { do_execsql_test fuzzer1-4.1 {