1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-08 03:22:21 +03:00

Prevent the fuzzer from ever returning a string longer than 100 bytes.

FossilOrigin-Name: 969095ca3067d60f4d3a0a4ad419541cb8b146db
This commit is contained in:
dan
2012-02-21 18:00:20 +00:00
parent 4965ebceb7
commit 99c7d468a7
5 changed files with 143 additions and 27 deletions

View File

@@ -180,9 +180,10 @@ typedef int fuzzer_ruleid;
/*
** Limits
*/
#define FUZZER_MX_LENGTH 50 /* Maximum length of a search string */
#define FUZZER_MX_LENGTH 50 /* Maximum length of a rule string */
#define FUZZER_MX_RULEID 2147483647 /* Maximum rule ID */
#define FUZZER_MX_COST 1000 /* Maximum single-rule cost */
#define FUZZER_MX_OUTPUT_LENGTH 100 /* Maximum length of an output string */
/*
@@ -612,8 +613,8 @@ static int fuzzerRender(
int *pnBuf /* Size of the buffer */
){
const fuzzer_rule *pRule = pStem->pRule;
int n;
char *z;
int n; /* Size of output term without nul-term */
char *z; /* Buffer to assemble output term in */
n = pStem->nBasis + pRule->nTo - pRule->nFrom;
if( (*pnBuf)<n+1 ){
@@ -631,6 +632,8 @@ static int fuzzerRender(
memcpy(&z[n+pRule->nTo], &pStem->zBasis[n+pRule->nFrom],
pStem->nBasis-n-pRule->nFrom+1);
}
assert( z[pStem->nBasis + pRule->nTo - pRule->nFrom]==0 );
return SQLITE_OK;
}
@@ -699,6 +702,25 @@ static int fuzzerSeen(fuzzer_cursor *pCur, fuzzer_stem *pStem){
return pLookup!=0;
}
/*
** If argument pRule is NULL, this function returns false.
**
** Otherwise, it returns true if rule pRule should be skipped. A rule
** should be skipped if it does not belong to rule-set iRuleset, or if
** applying it to stem pStem would create a string longer than
** FUZZER_MX_OUTPUT_LENGTH bytes.
*/
static int fuzzerSkipRule(
const fuzzer_rule *pRule, /* Determine whether or not to skip this */
fuzzer_stem *pStem, /* Stem rule may be applied to */
int iRuleset /* Rule-set used by the current query */
){
return pRule && (
(pRule->iRuleset!=iRuleset)
|| (pStem->nBasis + pRule->nTo - pRule->nFrom)>FUZZER_MX_OUTPUT_LENGTH
);
}
/*
** Advance a fuzzer_stem to its next value. Return 0 if there are
** no more values that can be generated by this fuzzer_stem. Return
@@ -706,7 +728,6 @@ static int fuzzerSeen(fuzzer_cursor *pCur, fuzzer_stem *pStem){
*/
static int fuzzerAdvance(fuzzer_cursor *pCur, fuzzer_stem *pStem){
const fuzzer_rule *pRule;
const int iSet = pCur->iRuleset;
while( (pRule = pStem->pRule)!=0 ){
assert( pRule==&pCur->nullRule || pRule->iRuleset==pCur->iRuleset );
while( pStem->n < pStem->nBasis - pRule->nFrom ){
@@ -726,7 +747,7 @@ static int fuzzerAdvance(fuzzer_cursor *pCur, fuzzer_stem *pStem){
pStem->n = -1;
do{
pRule = pRule->pNext;
}while( pRule && pRule->iRuleset!=iSet );
}while( fuzzerSkipRule(pRule, pStem, pCur->iRuleset) );
pStem->pRule = pRule;
if( pRule && fuzzerCost(pStem)>pCur->rLimit ) pStem->pRule = 0;
}
@@ -856,7 +877,7 @@ static fuzzer_stem *fuzzerNewStem(
pNew->nBasis = strlen(zWord);
memcpy(pNew->zBasis, zWord, pNew->nBasis+1);
pRule = pCur->pVtab->pRule;
while( pRule && pRule->iRuleset!=pCur->iRuleset ){
while( fuzzerSkipRule(pRule, pNew, pCur->iRuleset) ){
pRule = pRule->pNext;
}
pNew->pRule = pRule;
@@ -906,7 +927,10 @@ static int fuzzerNext(sqlite3_vtab_cursor *cur){
** stem list is the next lowest cost word.
*/
while( (pStem = pCur->pStem)!=0 ){
if( fuzzerAdvance(pCur, pStem) ){
int res = fuzzerAdvance(pCur, pStem);
if( res<0 ){
return SQLITE_NOMEM;
}else if( res>0 ){
pCur->pStem = 0;
pStem = fuzzerInsert(pCur, pStem);
if( (rc = fuzzerSeen(pCur, pStem))!=0 ){
@@ -944,7 +968,7 @@ static int fuzzerFilter(
int argc, sqlite3_value **argv
){
fuzzer_cursor *pCur = (fuzzer_cursor *)pVtabCursor;
const char *zWord = 0;
const char *zWord = "";
fuzzer_stem *pStem;
int idx;
@@ -963,17 +987,25 @@ static int fuzzerFilter(
pCur->iRuleset = (fuzzer_cost)sqlite3_value_int(argv[idx]);
idx++;
}
if( zWord==0 ) zWord = "";
pCur->pStem = pStem = fuzzerNewStem(pCur, zWord, (fuzzer_cost)0);
if( pStem==0 ) return SQLITE_NOMEM;
pCur->nullRule.pNext = pCur->pVtab->pRule;
pCur->nullRule.rCost = 0;
pCur->nullRule.nFrom = 0;
pCur->nullRule.nTo = 0;
pCur->nullRule.zFrom = "";
pStem->pRule = &pCur->nullRule;
pStem->n = pStem->nBasis;
pCur->iRowid = 1;
assert( pCur->pStem==0 );
/* If the query term is longer than FUZZER_MX_OUTPUT_LENGTH bytes, this
** query will return zero rows. */
if( strlen(zWord)<FUZZER_MX_OUTPUT_LENGTH ){
pCur->pStem = pStem = fuzzerNewStem(pCur, zWord, (fuzzer_cost)0);
if( pStem==0 ) return SQLITE_NOMEM;
pStem->pRule = &pCur->nullRule;
pStem->n = pStem->nBasis;
}else{
pCur->rLimit = 0;
}
return SQLITE_OK;
}
@@ -1156,7 +1188,7 @@ static int register_fuzzer_module(
Tcl_WrongNumArgs(interp, 1, objv, "DB");
return TCL_ERROR;
}
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
getDbPointer(interp, Tcl_GetString(objv[1]), &db);
fuzzer_register(db);
return TCL_OK;
}