From a0984eae14b2840a470800bb1bfb18bd99dc302b Mon Sep 17 00:00:00 2001 From: Patrick Monnerat Date: Wed, 7 Feb 2018 15:01:51 +0100 Subject: fnmatch: optimize processing of consecutive *s and ?s pattern characters Reported-By: Daniel Stenberg Fixes #2291 Closes #2293 --- lib/curl_fnmatch.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/lib/curl_fnmatch.c b/lib/curl_fnmatch.c index f303881d3..0179a4f71 100644 --- a/lib/curl_fnmatch.c +++ b/lib/curl_fnmatch.c @@ -256,7 +256,6 @@ static int loop(const unsigned char *pattern, const unsigned char *string, unsigned char *p = (unsigned char *)pattern; unsigned char *s = (unsigned char *)string; unsigned char charset[CURLFNM_CHSET_SIZE] = { 0 }; - int rc = 0; for(;;) { unsigned char *pp; @@ -265,18 +264,24 @@ static int loop(const unsigned char *pattern, const unsigned char *string, case '*': if(!maxstars) return CURL_FNMATCH_NOMATCH; - while(p[1] == '*') /* eliminate multiple stars */ - p++; - if(*s == '\0' && p[1] == '\0') - return CURL_FNMATCH_MATCH; - rc = loop(p + 1, s, maxstars - 1); /* *.txt matches .txt <=> - .txt matches .txt */ - if(rc == CURL_FNMATCH_MATCH) - return CURL_FNMATCH_MATCH; - if(!*s) - return CURL_FNMATCH_NOMATCH; - s++; /* let the star eat up one character */ - break; + /* Regroup consecutive stars and question marks. This can be done because + '*?*?*' can be expressed as '??*'. */ + for(;;) { + if(*++p == '\0') + return CURL_FNMATCH_MATCH; + if(*p == '?') { + if(!*s++) + return CURL_FNMATCH_NOMATCH; + } + else if(*p != '*') + break; + } + /* Skip string characters until we find a match with pattern suffix. */ + for(maxstars--; *s; s++) { + if(loop(p, s, maxstars) == CURL_FNMATCH_MATCH) + return CURL_FNMATCH_MATCH; + } + return CURL_FNMATCH_NOMATCH; case '?': if(!*s) return CURL_FNMATCH_NOMATCH; -- cgit v1.2.3