[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]