diff --git a/src/util.c b/src/util.c index eb6cd650c..942d9969f 100644 --- a/src/util.c +++ b/src/util.c @@ -33,8 +33,11 @@ /* Glob-style pattern matching. */ static int stringmatchlen_impl(const char *pattern, int patternLen, - const char *string, int stringLen, int nocase, int *skipLongerMatches) + const char *string, int stringLen, int nocase, int *skipLongerMatches, int nesting) { + /* Protection against abusive patterns. */ + if (nesting > 1000) return 0; + while(patternLen && stringLen) { switch(pattern[0]) { case '*': @@ -46,7 +49,7 @@ static int stringmatchlen_impl(const char *pattern, int patternLen, return 1; /* match */ while(stringLen) { if (stringmatchlen_impl(pattern+1, patternLen-1, - string, stringLen, nocase, skipLongerMatches)) + string, stringLen, nocase, skipLongerMatches, nesting+1)) return 1; /* match */ if (*skipLongerMatches) return 0; /* no match */ @@ -168,7 +171,7 @@ static int stringmatchlen_impl(const char *pattern, int patternLen, int stringmatchlen(const char *pattern, int patternLen, const char *string, int stringLen, int nocase) { int skipLongerMatches = 0; - return stringmatchlen_impl(pattern,patternLen,string,stringLen,nocase,&skipLongerMatches); + return stringmatchlen_impl(pattern,patternLen,string,stringLen,nocase,&skipLongerMatches,0); } int stringmatch(const char *pattern, const char *string, int nocase) { diff --git a/tests/unit/keyspace.tcl b/tests/unit/keyspace.tcl index abfda9cc6..03d8c9669 100644 --- a/tests/unit/keyspace.tcl +++ b/tests/unit/keyspace.tcl @@ -514,6 +514,12 @@ foreach {type large} [array get largevalue] { r KEYS "a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*b" } {} + test {Regression for pattern matching very long nested loops} { + r flushdb + r SET [string repeat "a" 50000] 1 + r KEYS [string repeat "*?" 50000] + } {} + test {Coverage: basic SWAPDB test and unhappy path} { r flushall r select 0