Module Name: othersrc
Committed By: lukem
Date: Wed Jan 23 05:13:48 UTC 2019
Modified Files:
othersrc/libexec/tnftpd/libnetbsd: fnmatch.c ftpfnmatch.h
Log Message:
sync to fnmatch.c 1.26, fnmatch.h
Update from NetBSD src/lib/libc/gen/fnmatch.c 1.18 to 1.26.
Update from NetBSD src/include/fnmatch.h 1.8 to 1.13.
Notable changes:
- Implement FNM_LEADING_DIR.
- Limit recursions to avoid DoS attacks. From Maksymilian Arciemowicz.
- Treat a backslash followed by NUL as NUL.
To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 othersrc/libexec/tnftpd/libnetbsd/fnmatch.c \
othersrc/libexec/tnftpd/libnetbsd/ftpfnmatch.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: othersrc/libexec/tnftpd/libnetbsd/fnmatch.c
diff -u othersrc/libexec/tnftpd/libnetbsd/fnmatch.c:1.3 othersrc/libexec/tnftpd/libnetbsd/fnmatch.c:1.4
--- othersrc/libexec/tnftpd/libnetbsd/fnmatch.c:1.3 Sun Sep 21 16:35:25 2008
+++ othersrc/libexec/tnftpd/libnetbsd/fnmatch.c Wed Jan 23 05:13:48 2019
@@ -1,5 +1,5 @@
-/* $NetBSD: fnmatch.c,v 1.3 2008/09/21 16:35:25 lukem Exp $ */
-/* from NetBSD: fnmatch.c,v 1.18 2000/06/28 01:13:36 thorpej Exp */
+/* $NetBSD: fnmatch.c,v 1.4 2019/01/23 05:13:48 lukem Exp $ */
+/* from NetBSD: fnmatch.c,v 1.26 2014/10/12 22:32:33 christos Exp */
/*
* Copyright (c) 1989, 1993, 1994
@@ -42,38 +42,83 @@
#define EOS '\0'
-static const char *rangematch(const char *, int, int);
-
-static int
+static inline int
foldcase(int ch, int flags)
{
if ((flags & FNM_CASEFOLD) != 0 && isupper(ch))
- return (tolower(ch));
- return (ch);
+ return tolower(ch);
+ return ch;
}
#define FOLDCASE(ch, flags) foldcase((unsigned char)(ch), (flags))
-int
-fnmatch(const char *pattern, const char *string, int flags)
+static const char *
+rangematch(const char *pattern, int test, int flags)
{
- const char *stringstart;
+ int negate, ok, need;
+ char c, c2;
+
+ /*
+ * A bracket expression starting with an unquoted circumflex
+ * character produces unspecified results (IEEE 1003.2-1992,
+ * 3.13.2). This implementation treats it like '!', for
+ * consistency with the regular expression syntax.
+ * J.T. Conklin ([email protected])
+ */
+ if ((negate = (*pattern == '!' || *pattern == '^')) != 0)
+ ++pattern;
+
+ need = 1;
+ for (ok = 0; (c = FOLDCASE(*pattern++, flags)) != ']' || need;) {
+ need = 0;
+ if (c == '/')
+ return (void *)-1;
+ if (c == '\\' && !(flags & FNM_NOESCAPE))
+ c = FOLDCASE(*pattern++, flags);
+ if (c == EOS)
+ return NULL;
+ if (*pattern == '-'
+ && (c2 = FOLDCASE(*(pattern + 1), flags)) != EOS &&
+ c2 != ']') {
+ pattern += 2;
+ if (c2 == '\\' && !(flags & FNM_NOESCAPE))
+ c2 = FOLDCASE(*pattern++, flags);
+ if (c2 == EOS)
+ return NULL;
+ if (c <= test && test <= c2)
+ ok = 1;
+ } else if (c == test)
+ ok = 1;
+ }
+ return ok == negate ? NULL : pattern;
+}
+
+
+static int
+fnmatchx(const char *pattern, const char *string, int flags, size_t recursion)
+{
+ const char *stringstart, *r;
char c, test;
- for (stringstart = string;;)
+ if (recursion-- == 0)
+ return FNM_NORES;
+
+ for (stringstart = string;;) {
switch (c = FOLDCASE(*pattern++, flags)) {
case EOS:
- return (*string == EOS ? 0 : FNM_NOMATCH);
+ if ((flags & FNM_LEADING_DIR) && *string == '/')
+ return 0;
+ return *string == EOS ? 0 : FNM_NOMATCH;
case '?':
if (*string == EOS)
- return (FNM_NOMATCH);
+ return FNM_NOMATCH;
if (*string == '/' && (flags & FNM_PATHNAME))
- return (FNM_NOMATCH);
+ return FNM_NOMATCH;
if (*string == '.' && (flags & FNM_PERIOD) &&
(string == stringstart ||
((flags & FNM_PATHNAME) && *(string - 1) == '/')))
- return (FNM_NOMATCH);
+ return FNM_NOMATCH;
++string;
break;
case '*':
@@ -85,91 +130,71 @@ fnmatch(const char *pattern, const char
if (*string == '.' && (flags & FNM_PERIOD) &&
(string == stringstart ||
((flags & FNM_PATHNAME) && *(string - 1) == '/')))
- return (FNM_NOMATCH);
+ return FNM_NOMATCH;
/* Optimize for pattern with * at end or before /. */
if (c == EOS) {
if (flags & FNM_PATHNAME)
- return (strchr(string, '/') == NULL ?
- 0 : FNM_NOMATCH);
+ return (flags & FNM_LEADING_DIR) ||
+ strchr(string, '/') == NULL ?
+ 0 : FNM_NOMATCH;
else
- return (0);
+ return 0;
} else if (c == '/' && flags & FNM_PATHNAME) {
if ((string = strchr(string, '/')) == NULL)
- return (FNM_NOMATCH);
+ return FNM_NOMATCH;
break;
}
/* General case, use recursion. */
while ((test = FOLDCASE(*string, flags)) != EOS) {
- if (!fnmatch(pattern, string,
- flags & ~FNM_PERIOD))
- return (0);
+ int e;
+ switch ((e = fnmatchx(pattern, string,
+ flags & ~FNM_PERIOD, recursion))) {
+ case FNM_NOMATCH:
+ break;
+ default:
+ return e;
+ }
if (test == '/' && flags & FNM_PATHNAME)
break;
++string;
}
- return (FNM_NOMATCH);
+ return FNM_NOMATCH;
case '[':
if (*string == EOS)
- return (FNM_NOMATCH);
+ return FNM_NOMATCH;
if (*string == '/' && flags & FNM_PATHNAME)
- return (FNM_NOMATCH);
- if ((pattern =
- rangematch(pattern, FOLDCASE(*string, flags),
- flags)) == NULL)
- return (FNM_NOMATCH);
+ return FNM_NOMATCH;
+ if ((r = rangematch(pattern,
+ FOLDCASE(*string, flags), flags)) == NULL)
+ return FNM_NOMATCH;
+ if (r == (void *)-1) {
+ if (*string != '[')
+ return FNM_NOMATCH;
+ } else
+ pattern = r;
++string;
break;
case '\\':
if (!(flags & FNM_NOESCAPE)) {
if ((c = FOLDCASE(*pattern++, flags)) == EOS) {
- c = '\\';
+ c = '\0';
--pattern;
}
}
/* FALLTHROUGH */
default:
if (c != FOLDCASE(*string++, flags))
- return (FNM_NOMATCH);
+ return FNM_NOMATCH;
break;
}
+ }
/* NOTREACHED */
}
-static const char *
-rangematch(const char *pattern, int test, int flags)
+int
+fnmatch(const char *pattern, const char *string, int flags)
{
- int negate, ok;
- char c, c2;
-
- /*
- * A bracket expression starting with an unquoted circumflex
- * character produces unspecified results (IEEE 1003.2-1992,
- * 3.13.2). This implementation treats it like '!', for
- * consistency with the regular expression syntax.
- * J.T. Conklin ([email protected])
- */
- if ((negate = (*pattern == '!' || *pattern == '^')) != 0)
- ++pattern;
-
- for (ok = 0; (c = FOLDCASE(*pattern++, flags)) != ']';) {
- if (c == '\\' && !(flags & FNM_NOESCAPE))
- c = FOLDCASE(*pattern++, flags);
- if (c == EOS)
- return (NULL);
- if (*pattern == '-'
- && (c2 = FOLDCASE(*(pattern+1), flags)) != EOS &&
- c2 != ']') {
- pattern += 2;
- if (c2 == '\\' && !(flags & FNM_NOESCAPE))
- c2 = FOLDCASE(*pattern++, flags);
- if (c2 == EOS)
- return (NULL);
- if (c <= test && test <= c2)
- ok = 1;
- } else if (c == test)
- ok = 1;
- }
- return (ok == negate ? NULL : pattern);
+ return fnmatchx(pattern, string, flags, 64);
}
Index: othersrc/libexec/tnftpd/libnetbsd/ftpfnmatch.h
diff -u othersrc/libexec/tnftpd/libnetbsd/ftpfnmatch.h:1.3 othersrc/libexec/tnftpd/libnetbsd/ftpfnmatch.h:1.4
--- othersrc/libexec/tnftpd/libnetbsd/ftpfnmatch.h:1.3 Sun Sep 21 16:35:25 2008
+++ othersrc/libexec/tnftpd/libnetbsd/ftpfnmatch.h Wed Jan 23 05:13:48 2019
@@ -1,5 +1,5 @@
-/* $NetBSD: ftpfnmatch.h,v 1.3 2008/09/21 16:35:25 lukem Exp $ */
-/* from NetBSD: fnmatch.h,v 1.8 2001/10/27 15:41:18 kleink Exp */
+/* $NetBSD: ftpfnmatch.h,v 1.4 2019/01/23 05:13:48 lukem Exp $ */
+/* from NetBSD: fnmatch.h,v 1.13 2011/01/31 04:49:46 christos Exp */
/*-
* Copyright (c) 1992, 1993
@@ -37,11 +37,13 @@
#define FNM_NOMATCH 1 /* Match failed. */
#define FNM_NOSYS 2 /* Function not implemented. */
+#define FNM_NORES 3 /* Out of resources */
#define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */
#define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */
#define FNM_PERIOD 0x04 /* Period must be matched by period. */
#define FNM_CASEFOLD 0x08 /* Pattern is matched case-insensitive */
+#define FNM_LEADING_DIR 0x10 /* Ignore /<tail> after Imatch. */
int fnmatch(const char *, const char *, int);