Fix for bugid #205 - work by Andrew Bartlet (modified to use
authorJeremy Allison <jra@samba.org>
Tue, 12 Aug 2003 04:25:26 +0000 (04:25 +0000)
committerJeremy Allison <jra@samba.org>
Tue, 12 Aug 2003 04:25:26 +0000 (04:25 +0000)
fixed buffer by me).
Jeremy.
(This used to be commit 6f68b8de4760a2103eae0a51b2aca356990ea526)

source3/lib/ms_fnmatch.c
source3/lib/util.c
source3/torture/masktest.c

index 106efa5bbcf449120ebf92b3c26622fc68f7b400..24232c3b523b1293e32f43b2e0c24574aa008324 100644 (file)
@@ -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);
 }
index eaa232a5494eb550ee012a6a0b233aa51486383e..efad01166effb1968143c6ab29adc79439d0cdf4 100644 (file)
@@ -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;
 }
 
 /*********************************************************
index fa901e3d63d4067ea54f410cbf89f9f0dd8c9a8f..8c44f35f958ea4f81ad922c7a54086384f7064c8 100644 (file)
@@ -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)