From 8996b91f97f143c89356d22dd08ce0a5aa2d6da2 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Tue, 21 Sep 2004 21:07:58 +0000 Subject: [PATCH] STABLE14-cifs-pattern-match-20040921 FIXES 15365 The pattern matching algorithm was failing to match strings when the pattern terminated in a '*'. The logic was also too complex because it failed to simply the patterns prior to processing. Any combination of '*' and '?' == '*' according to the Windows file name pattern matching rules. (cherry picked from commit a135e0d30c077e19c3f10f7a6ccc46fa3fb6c234) --- doc/txt/winnotes/afs-changes-since-1.2.txt | 3 + doc/txt/winnotes/afs-issues.txt | 10 +-- src/WINNT/afsd/smb3.c | 97 ++++++++++++++++------ 3 files changed, 77 insertions(+), 33 deletions(-) diff --git a/doc/txt/winnotes/afs-changes-since-1.2.txt b/doc/txt/winnotes/afs-changes-since-1.2.txt index 2dff4e8bee..1475bb97f5 100644 --- a/doc/txt/winnotes/afs-changes-since-1.2.txt +++ b/doc/txt/winnotes/afs-changes-since-1.2.txt @@ -1,4 +1,7 @@ Since 1.3.71: + * Fix the pattern matching algorithm to properly match patterns + ending with a '*'. + * smb_ReceiveCoreRename() was factored to produce smb_Rename() which is used by both the original function and the new smb_ReceiveNTRename(). smb_ReceiveNTRename() supports the diff --git a/doc/txt/winnotes/afs-issues.txt b/doc/txt/winnotes/afs-issues.txt index 44ce41ffd6..0d54904e70 100644 --- a/doc/txt/winnotes/afs-issues.txt +++ b/doc/txt/winnotes/afs-issues.txt @@ -196,10 +196,7 @@ List of unfunded projects: afsmap.exe /DELETE 22. Write-through caching appears to be unsupported. Files copied to AFS do not end up in the local cache. - 23. The Win32 API CreateHardLink() is not properly supported by the SMB/CIFS - server. It neither returns a valid error nor does it perform the - operation. - 24. Missing SMB/CIFS functions: + 23. Missing SMB/CIFS functions: Find FindUnique FindClose @@ -207,7 +204,8 @@ List of unfunded projects: WriteBulk WriteBulkData Tran2::SessionSetup + 24. StoreBehind mode is not implemented. Or more correctly, all data is + written directly to the server and is not cached. Writes invalidate + the local cache entries which are then read back from the server. - - diff --git a/src/WINNT/afsd/smb3.c b/src/WINNT/afsd/smb3.c index 117b729479..46be160bfb 100644 --- a/src/WINNT/afsd/smb3.c +++ b/src/WINNT/afsd/smb3.c @@ -3242,40 +3242,41 @@ VOID initUpperCaseTable(VOID) // Return value // BOOL : TRUE/FALSE (match/mistmatch) -BOOL szWildCardMatchFileName(PSZ pattern, PSZ name) { - PSZ pename; // points to the last 'name' character - PSZ p; - pename = name + strlen(name) - 1; - while (*name) { - switch (*pattern) { - case '?': - case '>': - if (*(++pattern) != '<' || *(++pattern) != '*') { - if (*name == '.') - return FALSE; - ++name; - break; - } /* endif */ - case '<': +BOOL +szWildCardMatchFileName(PSZ pattern, PSZ name) +{ + PSZ pename; // points to the last 'name' character + PSZ p; + pename = name + strlen(name) - 1; + while (*name) { + switch (*pattern) { + case '?': + if (*name == '.') + return FALSE; + ++pattern, ++name; + break; case '*': - while ((*pattern == '<') || (*pattern == '*') || (*pattern == '?') || (*pattern == '>')) - ++pattern; - if (!*pattern) + ++pattern; + if (*pattern == '\0') return TRUE; for (p = pename; p >= name; --p) { - if ((mapCaseTable[*p] == mapCaseTable[*pattern]) && - szWildCardMatchFileName(pattern + 1, p + 1)) - return TRUE; + if ((mapCaseTable[*p] == mapCaseTable[*pattern]) && + szWildCardMatchFileName(pattern + 1, p + 1)) + return TRUE; } /* endfor */ return FALSE; - default: + default: if (mapCaseTable[*name] != mapCaseTable[*pattern]) return FALSE; ++pattern, ++name; break; } /* endswitch */ } /* endwhile */ - return !*pattern; + + if (*pattern == '\0' || *pattern == '*' && *(pattern+1) == '\0') + return TRUE; + else + return FALSE; } /* do a case-folding search of the star name mask with the name in namep. @@ -3283,11 +3284,53 @@ BOOL szWildCardMatchFileName(PSZ pattern, PSZ name) { */ int smb_V3MatchMask(char *namep, char *maskp, int flags) { - /* make sure we only match 8.3 names, if requested */ - if ((flags & CM_FLAG_8DOT3) && !cm_Is8Dot3(namep)) + char * newmask; + int i, j, star, qmark, retval; + + /* make sure we only match 8.3 names, if requested */ + if ((flags & CM_FLAG_8DOT3) && !cm_Is8Dot3(namep)) return 0; - - return szWildCardMatchFileName(maskp, namep) ? 1:0; + + /* optimize the pattern: + * if there is a mixture of '?' and '*', + * for example the sequence "*?*?*?*" + * must be turned into the form "*" + */ + newmask = (char *)malloc(strlen(maskp)+1); + for ( i=0, j=0, star=0, qmark=0; maskp[i]; i++) { + switch ( maskp[i] ) { + case '?': + case '>': + qmark++; + break; + case '<': + case '*': + star++; + break; + default: + if ( star ) { + newmask[j++] = '*'; + } else if ( qmark ) { + while ( qmark-- ) + newmask[j++] = '?'; + } + newmask[j++] = maskp[i]; + star = 0; + qmark = 0; + } + } + if ( star ) { + newmask[j++] = '*'; + } else if ( qmark ) { + while ( qmark-- ) + newmask[j++] = '?'; + } + newmask[j++] = '\0'; + + retval = szWildCardMatchFileName(newmask, namep) ? 1:0; + + free(newmask); + return retval; } #else /* USE_OLD_MATCHING */