summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2018-05-31 15:57:54 +0200
committerDaniel Stenberg <daniel@haxx.se>2018-05-31 15:57:54 +0200
commit8f3bab4205e02aa4c2d8b36102e0e24a35f39bdc (patch)
treec95a5f4c8d4c9186565520039955ae874aa5917a
parent9c33813d835dde214c1a9449f789dd72ab3d9dc3 (diff)
downloadcurl-8f3bab4205e02aa4c2d8b36102e0e24a35f39bdc.tar.gz
fnmatch: use the system one if available
If configure detects fnmatch to be available, use that instead of our custom one for pattern matching. For standard compliance, to reduce our footprint and to use already well tested and well exercised code. A POSIX fnmatch behaves slightly different than the internal function for a few test patterns currently, and test 1307 is adjusted for this. This is considered a bug.
-rwxr-xr-xconfigure.ac3
-rw-r--r--lib/curl_fnmatch.c37
-rw-r--r--tests/unit/unit1307.c70
3 files changed, 95 insertions, 15 deletions
diff --git a/configure.ac b/configure.ac
index 9c4e697de..fa5dc84f5 100755
--- a/configure.ac
+++ b/configure.ac
@@ -3623,7 +3623,8 @@ AC_CHECK_DECLS([getpwuid_r], [], [AC_DEFINE(HAVE_DECL_GETPWUID_R_MISSING, 1, "Se
#include <sys/types.h>]])
-AC_CHECK_FUNCS([geteuid \
+AC_CHECK_FUNCS([fnmatch \
+ geteuid \
getpass_r \
getppid \
getpwuid \
diff --git a/lib/curl_fnmatch.c b/lib/curl_fnmatch.c
index bd4e61f4e..e8aff6761 100644
--- a/lib/curl_fnmatch.c
+++ b/lib/curl_fnmatch.c
@@ -30,6 +30,17 @@
/* The last #include file should be: */
#include "memdebug.h"
+#ifndef HAVE_FNMATCH
+
+/*
+ * TODO:
+ *
+ * Make this function match POSIX. Test 1307 includes a set of test patterns
+ * that returns different results with a POSIX fnmatch() than with this
+ * implemenation and this is considered a bug where POSIX is the guiding
+ * light.
+ */
+
#define CURLFNM_CHARSET_LEN (sizeof(char) * 256)
#define CURLFNM_CHSET_SIZE (CURLFNM_CHARSET_LEN + 15)
@@ -357,3 +368,29 @@ int Curl_fnmatch(void *ptr, const char *pattern, const char *string)
}
return loop((unsigned char *)pattern, (unsigned char *)string, 2);
}
+#else
+#include <fnmatch.h>
+/*
+ * @unittest: 1307
+ */
+int Curl_fnmatch(void *ptr, const char *pattern, const char *string)
+{
+ int rc;
+ (void)ptr; /* the argument is specified by the curl_fnmatch_callback
+ prototype, but not used by Curl_fnmatch() */
+ if(!pattern || !string) {
+ return CURL_FNMATCH_FAIL;
+ }
+ rc = fnmatch(pattern, string, 0);
+ switch(rc) {
+ case 0:
+ return CURL_FNMATCH_MATCH;
+ case FNM_NOMATCH:
+ return CURL_FNMATCH_NOMATCH;
+ default:
+ return CURL_FNMATCH_FAIL;
+ }
+ /* not reached */
+}
+
+#endif
diff --git a/tests/unit/unit1307.c b/tests/unit/unit1307.c
index fe16ed324..ed533bd6b 100644
--- a/tests/unit/unit1307.c
+++ b/tests/unit/unit1307.c
@@ -23,13 +23,23 @@
#include "curl_fnmatch.h"
+/*
+ CURL_FNMATCH_MATCH 0
+ CURL_FNMATCH_NOMATCH 1
+ CURL_FNMATCH_FAIL 2
+ */
+
#define MATCH CURL_FNMATCH_MATCH
#define NOMATCH CURL_FNMATCH_NOMATCH
+#define DIFFER 0x80
+#define POSIX_MATCH ((CURL_FNMATCH_MATCH << 8) | DIFFER)
+#define POSIX_NOMATCH ((CURL_FNMATCH_NOMATCH << 8) | DIFFER)
+#define POSIX_FAIL ((CURL_FNMATCH_FAIL << 8) | DIFFER)
struct testcase {
const char *pattern;
const char *string;
- int result;
+ int result;
};
static const struct testcase tests[] = {
@@ -43,8 +53,8 @@ static const struct testcase tests[] = {
NOMATCH},
{ "\\[", "[", MATCH },
- { "[", "[", NOMATCH },
- { "[]", "[]", NOMATCH },
+ { "[", "[", NOMATCH|POSIX_MATCH},
+ { "[]", "[]", NOMATCH|POSIX_MATCH},
{ "[][]", "[", MATCH },
{ "[][]", "]", MATCH },
{ "[[]", "[", MATCH },
@@ -86,7 +96,7 @@ static const struct testcase tests[] = {
{ "[][?*-]", "*", MATCH },
{ "[][?*-]", "-", MATCH },
{ "[]?*-]", "-", MATCH },
- { "[\xFF]", "\xFF", MATCH },
+ { "[\xFF]", "\xFF", MATCH | POSIX_FAIL},
{ "?/b/c", "a/b/c", MATCH },
{ "^_{}~", "^_{}~", MATCH },
{ "!#%+,-./01234567889", "!#%+,-./01234567889", MATCH },
@@ -108,9 +118,9 @@ static const struct testcase tests[] = {
{ "*[^a].t?t", "ba.txt", NOMATCH },
{ "*[^a].t?t", "ab.txt", MATCH },
{ "*[^a]", "", NOMATCH },
- { "[!\xFF]", "", NOMATCH },
- { "[!\xFF]", "\xFF", NOMATCH },
- { "[!\xFF]", "a", MATCH },
+ { "[!\xFF]", "", NOMATCH|POSIX_FAIL},
+ { "[!\xFF]", "\xFF", NOMATCH|POSIX_FAIL},
+ { "[!\xFF]", "a", MATCH | POSIX_FAIL},
{ "[!?*[]", "?", NOMATCH },
{ "[!!]", "!", NOMATCH },
{ "[!!]", "x", MATCH },
@@ -143,7 +153,7 @@ static const struct testcase tests[] = {
{ "[^[:print:]]", "\10", MATCH },
{ "[[:lower:]][[:lower:]]", "ll", MATCH },
{ "[[:foo:]]", "bar", NOMATCH },
- { "[[:foo:]]", "f]", MATCH },
+ { "[[:foo:]]", "f]", MATCH|POSIX_NOMATCH},
{ "Curl[[:blank:]];-)", "Curl ;-)", MATCH },
{ "*[[:blank:]]*", " ", MATCH },
@@ -181,7 +191,7 @@ static const struct testcase tests[] = {
{ "x", "", NOMATCH },
/* backslash */
- { "\\", "\\", MATCH },
+ { "\\", "\\", MATCH|POSIX_NOMATCH},
{ "\\\\", "\\", MATCH },
{ "\\\\", "\\\\", NOMATCH },
{ "\\?", "?", MATCH },
@@ -214,11 +224,11 @@ static const struct testcase tests[] = {
{ "Lindmätarv", "Lindmätarv", MATCH },
- { "", "", MATCH },
+ { "", "", MATCH},
{"**]*[*[\x13]**[*\x13)]*]*[**[*\x13~r-]*]**[.*]*[\xe3\xe3\xe3\xe3\xe3\xe3"
"\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3"
"\xe3\xe3\xe3\xe3\xe3*[\x13]**[*\x13)]*]*[*[\x13]*[~r]*]*\xba\x13\xa6~b-]*",
- "a", NOMATCH }
+ "a", NOMATCH|POSIX_FAIL}
};
static CURLcode unit_setup(void)
@@ -230,17 +240,49 @@ static void unit_stop(void)
{
}
+static const char *ret2name(int i)
+{
+ switch(i) {
+ case 0:
+ return "MATCH";
+ case 1:
+ return "NOMATCH";
+ case 2:
+ return "FAIL";
+ default:
+ return "unknown";
+ }
+ /* not reached */
+}
+
UNITTEST_START
int testnum = sizeof(tests) / sizeof(struct testcase);
int i, rc;
+ bool posix;
+
+#ifdef HAVE_FNMATCH
+ printf("Tested with system fnmatch()\n");
+ posix = TRUE;
+#else
+ printf("Tested with custom fnmatch()\n");
+ posix = FALSE;
+#endif
for(i = 0; i < testnum; i++) {
+ int result = tests[i].result;
rc = Curl_fnmatch(NULL, tests[i].pattern, tests[i].string);
- if(rc != tests[i].result) {
- printf("Curl_fnmatch(\"%s\", \"%s\") should return %d (returns %d)"
+ if(result & DIFFER) {
+ if(posix)
+ result >>= 8;
+ else
+ result &= 0x7f;
+ }
+ if(rc != result) {
+ printf("Curl_fnmatch(\"%s\", \"%s\") should return %s (returns %s)"
" [%d]\n",
- tests[i].pattern, tests[i].string, tests[i].result, rc, i);
+ tests[i].pattern, tests[i].string, ret2name(result),
+ ret2name(rc), i);
fail("pattern mismatch");
}
}