From cb5accab9ee3abdee777b59b463b5e0ca05a490a Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 13 Jan 2018 21:52:15 +0100 Subject: [PATCH] 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 --- lib/curl_fnmatch.c | 6 ++++-- tests/unit/unit1307.c | 25 ++++++++++++------------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/lib/curl_fnmatch.c b/lib/curl_fnmatch.c index 8a1e106c4..5638e167a 100644 --- a/lib/curl_fnmatch.c +++ b/lib/curl_fnmatch.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * 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) { p = pp + 1; - s++; + if(*s) + /* don't advance if we're matching on an empty string */ + s++; memset(charset, 0, CURLFNM_CHSET_SIZE); } else diff --git a/tests/unit/unit1307.c b/tests/unit/unit1307.c index 576462274..c5ec587a5 100644 --- a/tests/unit/unit1307.c +++ b/tests/unit/unit1307.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -27,12 +27,9 @@ #define NOMATCH CURL_FNMATCH_NOMATCH #define RE_ERR CURL_FNMATCH_FAIL -#define MAX_PATTERN_L 100 -#define MAX_STRING_L 100 - struct testcase { - char pattern[MAX_PATTERN_L]; - char string[MAX_STRING_L]; + const char *pattern; + const char *string; int result; }; @@ -100,6 +97,8 @@ static const struct testcase tests[] = { { "*[^a].t?t", "a.txt", NOMATCH }, { "*[^a].t?t", "ba.txt", NOMATCH }, { "*[^a].t?t", "ab.txt", MATCH }, + { "*[^a]", "", MATCH }, + { "[!ΓΏ]", "", MATCH }, { "[!?*[]", "?", NOMATCH }, { "[!!]", "!", NOMATCH }, { "[!!]", "x", MATCH }, @@ -119,17 +118,17 @@ static const struct testcase tests[] = { { "[[:lower:]]", "l", MATCH }, { "[[:lower:]]", "L", NOMATCH }, { "[[:print:]]", "L", MATCH }, - { "[[:print:]]", {'\10'}, NOMATCH }, - { "[[:print:]]", {'\10'}, NOMATCH }, + { "[[:print:]]", "\10", NOMATCH }, + { "[[:print:]]", "\10", NOMATCH }, { "[[:space:]]", " ", MATCH }, { "[[:space:]]", "x", NOMATCH }, { "[[:graph:]]", " ", NOMATCH }, { "[[:graph:]]", "x", MATCH }, - { "[[:blank:]]", {'\t'}, MATCH }, - { "[[:blank:]]", {' '}, MATCH }, - { "[[:blank:]]", {'\r'}, NOMATCH }, - { "[^[:blank:]]", {'\t'}, NOMATCH }, - { "[^[:print:]]", {'\10'}, MATCH }, + { "[[:blank:]]", "\t", MATCH }, + { "[[:blank:]]", " ", MATCH }, + { "[[:blank:]]", "\r", NOMATCH }, + { "[^[:blank:]]", "\t", NOMATCH }, + { "[^[:print:]]", "\10", MATCH }, { "[[:lower:]][[:lower:]]", "ll", MATCH }, { "Curl[[:blank:]];-)", "Curl ;-)", MATCH },