X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f X-Trace-PostClient-IP: 68.147.232.190 From: Brian Inglis Newsgroups: comp.os.msdos.djgpp Subject: Re: fnmatch("\\\\", "\\", 0) == 1 ??? Organization: Systematic Software Message-ID: References: <456dad03$0$486$cc7c7865 AT news DOT luth DOT se> <200611291634 DOT kATGYcbw010800 AT envy DOT delorie DOT com> X-Newsreader: Forte Agent 1.93/32.576 English (American) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Lines: 95 Date: Fri, 01 Dec 2006 10:49:42 GMT NNTP-Posting-Host: 64.59.135.176 X-Complaints-To: abuse AT shaw DOT ca X-Trace: pd7urf2no 1164970182 64.59.135.176 (Fri, 01 Dec 2006 03:49:42 MST) NNTP-Posting-Date: Fri, 01 Dec 2006 03:49:42 MST To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com On Wed, 29 Nov 2006 22:31:24 -0800 in comp.os.msdos.djgpp, "Alexei A. Frounze" wrote: >Brian Inglis wrote: >> fOn Wed, 29 Nov 2006 11:34:38 -0500 in comp.os.msdos.djgpp, DJ Delorie >> wrote: >> >>> >>>> This function indicates if STRING matches the PATTERN. ..." >>>> >>>> So DJGPP says that "\" doesn't match "\\" while Linux says it does. >>>> >>>> Well, I say DJGPP is right as the pattern says there should be two >>>> backslashes and you only provide one. >>> >>> Except that PATTERN is a regex influenced by FNM_NOESCAPE and >>> FNM_PATHNAME, and STRING isn't. So a pattern of "\\" is a single >>> escaped backslash, whereas a string of "\" is a single backslash. >>> They should match. >> >> switch ((c = *pattern++)) >> { >> ... >> ... >> ... >> case '\\': >> /*+++ pattern already post-incremented to point to next char */ >> if (!(flags & FNM_NOESCAPE) && pattern[1] && strchr("*?[\\", >> pattern[1])) >> /*+++ should be: >> if (!(flags & FNM_NOESCAPE) && strchr("*?[\\", *pattern)) >> *+++ as end of input pattern will match end char in escapes string */ >> { >> /*+++ end of input pattern might be clearer with ! or == '\0' */ >> if ((c = *pattern++) == 0) >> { >> c = '\\'; >> --pattern; >> } >> if (c != *string++) >> return FNM_NOMATCH; >> break; >> } > >I don't think the above is enough. There's another problem. With the above >code you'd never see (c = *pattern++) == 0. My bet is that the intent was to >treat the slash in the last character of pattern as an ordinary character. AFAICS it does: strchr matches the nul pattern terminator with the nul escapes constant terminator and returns a pointer to that character, so the result is non-zero/true, as noted in the third +++ line. If "&& *pattern &&" was included, and a nul pattern terminator was encountered, that if statement would be false and fallthrough to the following default case, which is clearly not intended by the subsequent test for the nul pattern terminator, which fixes things up to treat a terminal \ as an ordinary character. >That would explain the {c = '\\'; --pattern;} thing along with the >fallthrough behavior. The break ensures that the fallthrough default case is skipped if an escape is valid and there is a match, otherwise the previous return happens. >But the code is broken in this place. Dunno if it was >tested against the single unix spec or just a little bit to see that it >seems to work (in some basic cases). Handling of non-special escape characters here is punted to the fallthrough default case and treated the same as FNM_NOESCAPE! Not sure if that is intentional or just inadequate. If non-special escape characters should be treated as a literal character, the strchr() should be eliminated and only the nul terminator handled specially as it is. The resulting code would look like: case '\\': /* escape or directory */ if (!(flags & FNM_NOESCAPE)) /* if escapes allowed */ { if ((c = *pattern++) == '\0') /* if next char end */ { c = '\\'; /* trailing \ stays put */ --pattern; /* backup ptr to end */ } if (c != *string++) /* mismatch */ return FNM_NOMATCH; /* quit */ break; /* done */ } -- Thanks. Take care, Brian Inglis Calgary, Alberta, Canada Brian DOT Inglis AT CSi DOT com (Brian[dot]Inglis{at}SystematicSW[dot]ab[dot]ca) fake address use address above to reply