ftp-wildcard: fix matching an empty string with "*[^a]"

.... and avoid advancing the pointer to trigger an out of buffer read.

Detected by OSS-fuzz
Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=5251
Assisted-by: Max Dymond
This commit is contained in:
Daniel Stenberg 2018-01-13 21:52:15 +01:00
parent 25c40c9af9
commit cb5accab9e
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
2 changed files with 16 additions and 15 deletions

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@ -376,7 +376,9 @@ static int loop(const unsigned char *pattern, const unsigned char *string)
if(found) { if(found) {
p = pp + 1; p = pp + 1;
s++; if(*s)
/* don't advance if we're matching on an empty string */
s++;
memset(charset, 0, CURLFNM_CHSET_SIZE); memset(charset, 0, CURLFNM_CHSET_SIZE);
} }
else else

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@ -27,12 +27,9 @@
#define NOMATCH CURL_FNMATCH_NOMATCH #define NOMATCH CURL_FNMATCH_NOMATCH
#define RE_ERR CURL_FNMATCH_FAIL #define RE_ERR CURL_FNMATCH_FAIL
#define MAX_PATTERN_L 100
#define MAX_STRING_L 100
struct testcase { struct testcase {
char pattern[MAX_PATTERN_L]; const char *pattern;
char string[MAX_STRING_L]; const char *string;
int result; int result;
}; };
@ -100,6 +97,8 @@ static const struct testcase tests[] = {
{ "*[^a].t?t", "a.txt", NOMATCH }, { "*[^a].t?t", "a.txt", NOMATCH },
{ "*[^a].t?t", "ba.txt", NOMATCH }, { "*[^a].t?t", "ba.txt", NOMATCH },
{ "*[^a].t?t", "ab.txt", MATCH }, { "*[^a].t?t", "ab.txt", MATCH },
{ "*[^a]", "", MATCH },
{ "[!ÿ]", "", MATCH },
{ "[!?*[]", "?", NOMATCH }, { "[!?*[]", "?", NOMATCH },
{ "[!!]", "!", NOMATCH }, { "[!!]", "!", NOMATCH },
{ "[!!]", "x", MATCH }, { "[!!]", "x", MATCH },
@ -119,17 +118,17 @@ static const struct testcase tests[] = {
{ "[[:lower:]]", "l", MATCH }, { "[[:lower:]]", "l", MATCH },
{ "[[:lower:]]", "L", NOMATCH }, { "[[:lower:]]", "L", NOMATCH },
{ "[[:print:]]", "L", MATCH }, { "[[:print:]]", "L", MATCH },
{ "[[:print:]]", {'\10'}, NOMATCH }, { "[[:print:]]", "\10", NOMATCH },
{ "[[:print:]]", {'\10'}, NOMATCH }, { "[[:print:]]", "\10", NOMATCH },
{ "[[:space:]]", " ", MATCH }, { "[[:space:]]", " ", MATCH },
{ "[[:space:]]", "x", NOMATCH }, { "[[:space:]]", "x", NOMATCH },
{ "[[:graph:]]", " ", NOMATCH }, { "[[:graph:]]", " ", NOMATCH },
{ "[[:graph:]]", "x", MATCH }, { "[[:graph:]]", "x", MATCH },
{ "[[:blank:]]", {'\t'}, MATCH }, { "[[:blank:]]", "\t", MATCH },
{ "[[:blank:]]", {' '}, MATCH }, { "[[:blank:]]", " ", MATCH },
{ "[[:blank:]]", {'\r'}, NOMATCH }, { "[[:blank:]]", "\r", NOMATCH },
{ "[^[:blank:]]", {'\t'}, NOMATCH }, { "[^[:blank:]]", "\t", NOMATCH },
{ "[^[:print:]]", {'\10'}, MATCH }, { "[^[:print:]]", "\10", MATCH },
{ "[[:lower:]][[:lower:]]", "ll", MATCH }, { "[[:lower:]][[:lower:]]", "ll", MATCH },
{ "Curl[[:blank:]];-)", "Curl ;-)", MATCH }, { "Curl[[:blank:]];-)", "Curl ;-)", MATCH },