From 0640b3c2cd8c32c47dea8e750de5f29c6e78f4c4 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Tue, 6 Jan 2004 01:05:52 +0000 Subject: [PATCH] Maintain the fnmatch() API from FreeBSD-5 using an inline, rename the core fnmatch procedure to _fnmatch, and add a nesting count to it to avoid stack overflows. Also cleanup the syntax (mainly add braces and ansification). --- sys/libkern/fnmatch.c | 52 ++++++++++++++++++++++++------------------- sys/sys/libkern.h | 9 ++++++-- 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/sys/libkern/fnmatch.c b/sys/libkern/fnmatch.c index f2e7125a86..31399be634 100644 --- a/sys/libkern/fnmatch.c +++ b/sys/libkern/fnmatch.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/libkern/fnmatch.c,v 1.17 2003/06/11 05:23:04 obrien Exp $ - * $DragonFly: src/sys/libkern/fnmatch.c,v 1.1 2004/01/06 00:56:47 dillon Exp $ + * $DragonFly: src/sys/libkern/fnmatch.c,v 1.2 2004/01/06 01:05:52 dillon Exp $ */ /* @@ -52,18 +52,21 @@ #define RANGE_NOMATCH 0 #define RANGE_ERROR (-1) +#define MAXNEST 20 + static int rangematch(const char *, char, int, char **); int -fnmatch(pattern, string, flags) - const char *pattern, *string; - int flags; +_fnmatch(const char *pattern, const char *string, int flags, int nesting) { const char *stringstart; char *newp; char c, test; - for (stringstart = string;;) + if (nesting == MAXNEST) + return (FNM_NOMATCH); + + for (stringstart = string;;) { switch (c = *pattern++) { case EOS: if ((flags & FNM_LEADING_DIR) && *string == '/') @@ -76,8 +79,9 @@ fnmatch(pattern, string, flags) return (FNM_NOMATCH); if (*string == '.' && (flags & FNM_PERIOD) && (string == stringstart || - ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) { return (FNM_NOMATCH); + } ++string; break; case '*': @@ -88,18 +92,20 @@ fnmatch(pattern, string, flags) if (*string == '.' && (flags & FNM_PERIOD) && (string == stringstart || - ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) { return (FNM_NOMATCH); + } /* Optimize for pattern with * at end or before /. */ - if (c == EOS) - if (flags & FNM_PATHNAME) + if (c == EOS) { + if (flags & FNM_PATHNAME) { return ((flags & FNM_LEADING_DIR) || index(string, '/') == NULL ? 0 : FNM_NOMATCH); - else + } else { return (0); - else if (c == '/' && flags & FNM_PATHNAME) { + } + } else if (c == '/' && flags & FNM_PATHNAME) { if ((string = index(string, '/')) == NULL) return (FNM_NOMATCH); break; @@ -107,7 +113,7 @@ fnmatch(pattern, string, flags) /* General case, use recursion. */ while ((test = *string) != EOS) { - if (!fnmatch(pattern, string, flags & ~FNM_PERIOD)) + if (!_fnmatch(pattern, string, flags & ~FNM_PERIOD, nesting + 1)) return (0); if (test == '/' && flags & FNM_PATHNAME) break; @@ -145,26 +151,24 @@ fnmatch(pattern, string, flags) /* FALLTHROUGH */ default: norm: - if (c == *string) + if (c == *string) { ; - else if ((flags & FNM_CASEFOLD) && + } else if ((flags & FNM_CASEFOLD) && (tolower((unsigned char)c) == - tolower((unsigned char)*string))) + tolower((unsigned char)*string))) { ; - else + } else { return (FNM_NOMATCH); + } string++; break; } + } /* NOTREACHED */ } static int -rangematch(pattern, test, flags, newp) - const char *pattern; - char test; - int flags; - char **newp; +rangematch(const char *pattern, char test, int flags, char **newp) { int negate, ok; char c, c2; @@ -176,7 +180,7 @@ rangematch(pattern, test, flags, newp) * consistency with the regular expression syntax. * J.T. Conklin (conklin@ngai.kaleida.com) */ - if ( (negate = (*pattern == '!' || *pattern == '^')) ) + if ((negate = (*pattern == '!' || *pattern == '^')) != 0) ++pattern; if (flags & FNM_CASEFOLD) @@ -214,10 +218,12 @@ rangematch(pattern, test, flags, newp) if (c <= test && test <= c2) ok = 1; - } else if (c == test) + } else if (c == test) { ok = 1; + } } while ((c = *pattern++) != ']'); *newp = (char *)(uintptr_t)pattern; return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH); } + diff --git a/sys/sys/libkern.h b/sys/sys/libkern.h index 7b29b09ebb..8e77207f27 100644 --- a/sys/sys/libkern.h +++ b/sys/sys/libkern.h @@ -32,7 +32,7 @@ * * @(#)libkern.h 8.1 (Berkeley) 6/10/93 * $FreeBSD: src/sys/sys/libkern.h,v 1.20.2.2 2001/09/30 21:12:54 luigi Exp $ - * $DragonFly: src/sys/sys/libkern.h,v 1.5 2004/01/06 00:56:42 dillon Exp $ + * $DragonFly: src/sys/sys/libkern.h,v 1.6 2004/01/06 01:05:51 dillon Exp $ */ #ifndef _SYS_LIBKERN_H_ @@ -73,7 +73,6 @@ int ffs (int); #ifndef HAVE_INLINE_FLS int fls (int); #endif -int fnmatch(const char *, const char *, int); int locc (int, char *, u_int); void qsort (void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); @@ -91,7 +90,13 @@ size_t strlcpy (char *, const char *, size_t); size_t strlen (const char *); int strncmp (const char *, const char *, size_t); char *strncpy (char *, const char *, size_t); +int _fnmatch(const char *, const char *, int, int); +static __inline int +fnmatch(const char *pattern, const char *string, int flags) +{ + return(_fnmatch(pattern, string, flags, 0)); +} static __inline int memcmp(const void *b1, const void *b2, size_t len) -- 2.41.0