From aed1610ec22bb3eb283f548892fb9e00917df5f7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 Aug 2003 04:25:26 +0000 Subject: Fix for bugid #205 - work by Andrew Bartlet (modified to use fixed buffer by me). Jeremy. (This used to be commit 6f68b8de4760a2103eae0a51b2aca356990ea526) --- source3/lib/ms_fnmatch.c | 82 ++++++++++++++++++++++++++++++---------------- source3/lib/util.c | 11 +------ source3/torture/masktest.c | 2 +- 3 files changed, 55 insertions(+), 40 deletions(-) diff --git a/source3/lib/ms_fnmatch.c b/source3/lib/ms_fnmatch.c index 106efa5bbc..24232c3b52 100644 --- a/source3/lib/ms_fnmatch.c +++ b/source3/lib/ms_fnmatch.c @@ -35,7 +35,8 @@ of the protocol. This is not yet perfect, but its a lot better than what we had */ static int ms_fnmatch_lanman_core(const smb_ucs2_t *pattern, - const smb_ucs2_t *string) + const smb_ucs2_t *string, + BOOL case_sensitive) { const smb_ucs2_t *p = pattern, *n = string; smb_ucs2_t c; @@ -61,8 +62,8 @@ static int ms_fnmatch_lanman_core(const smb_ucs2_t *pattern, case UCS2_CHAR('>'): if (! *n) goto next; if (n[0] == UCS2_CHAR('.')) { - if (! n[1] && ms_fnmatch_lanman_core(p, n+1) == 0) goto match; - if (ms_fnmatch_lanman_core(p, n) == 0) goto match; + if (! n[1] && ms_fnmatch_lanman_core(p, n+1, case_sensitive) == 0) goto match; + if (ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match; goto nomatch; } n++; @@ -72,13 +73,13 @@ static int ms_fnmatch_lanman_core(const smb_ucs2_t *pattern, if (! *n) goto next; if (! *p) goto match; for (; *n; n++) { - if (ms_fnmatch_lanman_core(p, n) == 0) goto match; + if (ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match; } break; case UCS2_CHAR('<'): for (; *n; n++) { - if (ms_fnmatch_lanman_core(p, n) == 0) goto match; + if (ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match; if (*n == UCS2_CHAR('.') && !strchr_w(n+1,UCS2_CHAR('.'))) { n++; @@ -88,13 +89,17 @@ static int ms_fnmatch_lanman_core(const smb_ucs2_t *pattern, break; case UCS2_CHAR('"'): - if (*n == 0 && ms_fnmatch_lanman_core(p, n) == 0) goto match; + if (*n == 0 && ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match; if (*n != UCS2_CHAR('.')) goto nomatch; n++; break; default: - if (c != *n) goto nomatch; + if (case_sensitive) { + if (c != *n) goto nomatch; + } else { + if (tolower_w(c) != tolower_w(*n)) goto nomatch; + } n++; } } @@ -108,7 +113,7 @@ static int ms_fnmatch_lanman_core(const smb_ucs2_t *pattern, return -1; next: - if (ms_fnmatch_lanman_core(p, n) == 0) goto match; + if (ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match; goto nomatch; match: @@ -118,7 +123,8 @@ next: return 0; } -static int ms_fnmatch_lanman1(const smb_ucs2_t *pattern, const smb_ucs2_t *string) +static int ms_fnmatch_lanman1(const smb_ucs2_t *pattern, + const smb_ucs2_t *string, BOOL case_sensitive) { if (!strpbrk_wa(pattern, "?*<>\"")) { smb_ucs2_t s[] = {UCS2_CHAR('.'), 0}; @@ -129,11 +135,11 @@ static int ms_fnmatch_lanman1(const smb_ucs2_t *pattern, const smb_ucs2_t *strin if (strcmp_wa(string,"..") == 0 || strcmp_wa(string,".") == 0) { smb_ucs2_t dot[] = {UCS2_CHAR('.'), 0}; smb_ucs2_t dotdot[] = {UCS2_CHAR('.'), UCS2_CHAR('.'), 0}; - return ms_fnmatch_lanman_core(pattern, dotdot) && - ms_fnmatch_lanman_core(pattern, dot); + return ms_fnmatch_lanman_core(pattern, dotdot, case_sensitive) && + ms_fnmatch_lanman_core(pattern, dot, case_sensitive); } - return ms_fnmatch_lanman_core(pattern, string); + return ms_fnmatch_lanman_core(pattern, string, case_sensitive); } @@ -145,13 +151,14 @@ static int ms_fnmatch_lanman1(const smb_ucs2_t *pattern, const smb_ucs2_t *strin Returns 0 on match, -1 on fail. */ -static int ms_fnmatch_w(const smb_ucs2_t *pattern, const smb_ucs2_t *string, int protocol) +static int ms_fnmatch_w(const smb_ucs2_t *pattern, const smb_ucs2_t *string, + int protocol, BOOL case_sensitive) { const smb_ucs2_t *p = pattern, *n = string; smb_ucs2_t c; if (protocol <= PROTOCOL_LANMAN2) { - return ms_fnmatch_lanman1(pattern, string); + return ms_fnmatch_lanman1(pattern, string, case_sensitive); } while ((c = *p++)) { @@ -163,23 +170,23 @@ static int ms_fnmatch_w(const smb_ucs2_t *pattern, const smb_ucs2_t *string, int case UCS2_CHAR('>'): if (n[0] == UCS2_CHAR('.')) { - if (! n[1] && ms_fnmatch_w(p, n+1, protocol) == 0) return 0; - if (ms_fnmatch_w(p, n, protocol) == 0) return 0; + if (! n[1] && ms_fnmatch_w(p, n+1, protocol, case_sensitive) == 0) return 0; + if (ms_fnmatch_w(p, n, protocol, case_sensitive) == 0) return 0; return -1; } - if (! *n) return ms_fnmatch_w(p, n, protocol); + if (! *n) return ms_fnmatch_w(p, n, protocol, case_sensitive); n++; break; case UCS2_CHAR('*'): for (; *n; n++) { - if (ms_fnmatch_w(p, n, protocol) == 0) return 0; + if (ms_fnmatch_w(p, n, protocol, case_sensitive) == 0) return 0; } break; case UCS2_CHAR('<'): for (; *n; n++) { - if (ms_fnmatch_w(p, n, protocol) == 0) return 0; + if (ms_fnmatch_w(p, n, protocol, case_sensitive) == 0) return 0; if (*n == UCS2_CHAR('.') && !strchr_wa(n+1,'.')) { n++; break; @@ -188,13 +195,17 @@ static int ms_fnmatch_w(const smb_ucs2_t *pattern, const smb_ucs2_t *string, int break; case UCS2_CHAR('"'): - if (*n == 0 && ms_fnmatch_w(p, n, protocol) == 0) return 0; + if (*n == 0 && ms_fnmatch_w(p, n, protocol, case_sensitive) == 0) return 0; if (*n != UCS2_CHAR('.')) return -1; n++; break; default: - if (c != *n) return -1; + if (case_sensitive) { + if (c != *n) return -1; + } else { + if (tolower_w(c) != tolower_w(*n)) return -1; + } n++; } } @@ -204,22 +215,35 @@ static int ms_fnmatch_w(const smb_ucs2_t *pattern, const smb_ucs2_t *string, int return -1; } - -int ms_fnmatch(const char *pattern, const char *string, int protocol) +int ms_fnmatch(const char *pattern, const char *string, int protocol, + BOOL case_senstive) { - wpstring p, s; + wpstring buffer_pattern, buffer_string; int ret; + size_t size; + + size = push_ucs2(NULL, buffer_pattern, pattern, sizeof(buffer_pattern), STR_TERMINATE); + if (size == (size_t)-1) { + return -1; + /* Not quite the right answer, but finding the right one + under this failure case is expensive, and it's pretty close */ + } + + size = push_ucs2(NULL, buffer_string, string, sizeof(buffer_string), STR_TERMINATE); + if (size == (size_t)-1) { + return -1; + /* Not quite the right answer, but finding the right one + under this failure case is expensive, and it's pretty close */ + } - pstrcpy_wa(p, pattern); - pstrcpy_wa(s, string); + ret = ms_fnmatch_w(buffer_pattern, buffer_string, protocol, case_senstive); + DEBUG(10,("ms_fnmatch(%s,%s) -> %d\n", pattern, string, ret)); - ret = ms_fnmatch_w(p, s, protocol); -/* DEBUG(0,("ms_fnmatch(%s,%s) -> %d\n", pattern, string, ret)); */ return ret; } /* a generic fnmatch function - uses for non-CIFS pattern matching */ int gen_fnmatch(const char *pattern, const char *string) { - return ms_fnmatch(pattern, string, PROTOCOL_NT1); + return ms_fnmatch(pattern, string, PROTOCOL_NT1, True); } diff --git a/source3/lib/util.c b/source3/lib/util.c index eaa232a549..efad01166e 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -2335,21 +2335,12 @@ BOOL ms_has_wild_w(const smb_ucs2_t *s) BOOL mask_match(const char *string, char *pattern, BOOL is_case_sensitive) { - fstring p2, s2; - if (strcmp(string,"..") == 0) string = "."; if (strcmp(pattern,".") == 0) return False; - if (is_case_sensitive) - return ms_fnmatch(pattern, string, Protocol) == 0; - - fstrcpy(p2, pattern); - fstrcpy(s2, string); - strlower_m(p2); - strlower_m(s2); - return ms_fnmatch(p2, s2, Protocol) == 0; + return ms_fnmatch(pattern, string, Protocol, is_case_sensitive) == 0; } /********************************************************* diff --git a/source3/torture/masktest.c b/source3/torture/masktest.c index fa901e3d63..8c44f35f95 100644 --- a/source3/torture/masktest.c +++ b/source3/torture/masktest.c @@ -140,7 +140,7 @@ static BOOL reg_match_one(struct cli_state *cli, const char *pattern, const char if (strcmp(file,"..") == 0) file = "."; - return ms_fnmatch(pattern, file, cli->protocol)==0; + return ms_fnmatch(pattern, file, cli->protocol, False /* not case sensitive */)==0; } static char *reg_test(struct cli_state *cli, char *pattern, char *long_name, char *short_name) -- cgit