summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2003-08-12 04:25:26 +0000
committerJeremy Allison <jra@samba.org>2003-08-12 04:25:26 +0000
commitaed1610ec22bb3eb283f548892fb9e00917df5f7 (patch)
treefbc3bbec10a16a8627375ce446ea8438fe1e1777
parent61a1fa97afd500e29d2ae3119412a34d39baf3c6 (diff)
downloadsamba-aed1610ec22bb3eb283f548892fb9e00917df5f7.tar.gz
samba-aed1610ec22bb3eb283f548892fb9e00917df5f7.tar.bz2
samba-aed1610ec22bb3eb283f548892fb9e00917df5f7.zip
Fix for bugid #205 - work by Andrew Bartlet (modified to use
fixed buffer by me). Jeremy. (This used to be commit 6f68b8de4760a2103eae0a51b2aca356990ea526)
-rw-r--r--source3/lib/ms_fnmatch.c82
-rw-r--r--source3/lib/util.c11
-rw-r--r--source3/torture/masktest.c2
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)