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:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user