ruby-changes:33884
From: nobu <ko1@a...>
Date: Sat, 17 May 2014 01:49:57 +0900 (JST)
Subject: [ruby-changes:33884] nobu:r45965 (trunk): dir.c: match plain names as-is
nobu 2014-05-17 01:49:25 +0900 (Sat, 17 May 2014) New Revision: 45965 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=45965 Log: dir.c: match plain names as-is * dir.c (glob_pattern_type): separate names with alphabet but no magical from plain. * dir.c (glob_helper): match plain names as-is to treat super-root same as the root. [ruby-core:61552] [Bug #9648] Modified files: trunk/ChangeLog trunk/dir.c trunk/test/ruby/test_dir.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 45964) +++ ChangeLog (revision 45965) @@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sat May 17 01:49:23 2014 Nobuyoshi Nakada <nobu@r...> + + * dir.c (glob_pattern_type): separate names with alphabet but no + magical from plain. + + * dir.c (glob_helper): match plain names as-is to treat super-root + same as the root. [ruby-core:61552] [Bug #9648] + Fri May 16 17:38:22 2014 Koichi Sasada <ko1@a...> * gc.c (gc_marks, gc_marks_body): increase the counter of young objects Index: dir.c =================================================================== --- dir.c (revision 45964) +++ dir.c (revision 45965) @@ -1086,12 +1086,16 @@ do_opendir(const char *path, int flags, https://github.com/ruby/ruby/blob/trunk/dir.c#L1086 return dirp; } +/* Globing pattern */ +enum glob_pattern_type { PLAIN, ALPHA, MAGICAL, RECURSIVE, MATCH_ALL, MATCH_DIR }; + /* Return nonzero if S has any special globbing chars in it. */ -static int +static enum glob_pattern_type has_magic(const char *p, const char *pend, int flags, rb_encoding *enc) { const int escape = !(flags & FNM_NOESCAPE); const int nocase = flags & FNM_CASEFOLD; + int hasalpha = 0; register char c; @@ -1100,22 +1104,23 @@ has_magic(const char *p, const char *pen https://github.com/ruby/ruby/blob/trunk/dir.c#L1104 case '*': case '?': case '[': - return 1; + return MAGICAL; case '\\': if (escape && !(c = *p++)) - return 0; + return PLAIN; continue; default: - if (!FNM_SYSCASE && ISALPHA(c) && nocase) - return 1; + if (ISALPHA(c)) { + if (FNM_SYSCASE || nocase) hasalpha = 1; + } } p = Next(p-1, pend, enc); } - return 0; + return hasalpha ? ALPHA : PLAIN; } /* Find separator in globbing pattern. */ @@ -1179,9 +1184,6 @@ remove_backslashes(char *p, register con https://github.com/ruby/ruby/blob/trunk/dir.c#L1184 return p; } -/* Globing pattern */ -enum glob_pattern_type { PLAIN, MAGICAL, RECURSIVE, MATCH_ALL, MATCH_DIR }; - struct glob_pattern { char *str; enum glob_pattern_type type; @@ -1210,12 +1212,13 @@ glob_make_pattern(const char *p, const c https://github.com/ruby/ruby/blob/trunk/dir.c#L1212 } else { const char *m = find_dirsep(p, e, flags, enc); - const int magic = has_magic(p, m, flags, enc); + const enum glob_pattern_type magic = has_magic(p, m, flags, enc); + const enum glob_pattern_type non_magic = (HAVE_HFS || FNM_SYSCASE) ? PLAIN : ALPHA; char *buf; - if (!(FNM_SYSCASE || HAVE_HFS || magic) && !recursive && *m) { + if (!(FNM_SYSCASE || magic > non_magic) && !recursive && *m) { const char *m2; - while (!has_magic(m+1, m2 = find_dirsep(m+1, e, flags, enc), flags, enc) && + while (has_magic(m+1, m2 = find_dirsep(m+1, e, flags, enc), flags, enc) <= non_magic && *m2) { m = m2; } @@ -1227,7 +1230,7 @@ glob_make_pattern(const char *p, const c https://github.com/ruby/ruby/blob/trunk/dir.c#L1230 } memcpy(buf, p, m-p); buf[m-p] = '\0'; - tmp->type = magic ? MAGICAL : PLAIN; + tmp->type = magic > MAGICAL ? MAGICAL : magic; tmp->str = buf; if (*m) { dirsep = 1; @@ -1346,6 +1349,7 @@ glob_helper( https://github.com/ruby/ruby/blob/trunk/dir.c#L1349 case PLAIN: plain = 1; break; + case ALPHA: case MAGICAL: magical = 1; break; @@ -1397,7 +1401,7 @@ glob_helper( https://github.com/ruby/ruby/blob/trunk/dir.c#L1401 if (exist == NO || isdir == NO) return 0; - if (magical || recursive || ((FNM_SYSCASE || HAVE_HFS) && plain)) { + if (magical || recursive) { struct dirent *dp; DIR *dirp; IF_HAVE_HFS(int hfs_p); @@ -1483,9 +1487,13 @@ glob_helper( https://github.com/ruby/ruby/blob/trunk/dir.c#L1487 *new_end++ = p; /* append recursive pattern */ p = p->next; /* 0 times recursion */ } - if (p->type == PLAIN || p->type == MAGICAL) { + switch (p->type) { + case ALPHA: + case MAGICAL: if (fnmatch(p->str, enc, name, flags) == 0) *new_end++ = p->next; + default: + break; } } Index: test/ruby/test_dir.rb =================================================================== --- test/ruby/test_dir.rb (revision 45964) +++ test/ruby/test_dir.rb (revision 45965) @@ -249,6 +249,12 @@ class TestDir < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_dir.rb#L249 end end + def test_glob_super_root + bug9648 = '[ruby-core:61552] [Bug #9648]' + roots = Dir.glob("/*") + assert_equal(roots.map {|n| "/..#{n}"}, Dir.glob("/../*"), bug9648) + end + def test_home env_home = ENV["HOME"] env_logdir = ENV["LOGDIR"] -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/