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

ruby-changes:50325

From: nagachika <ko1@a...>
Date: Sat, 17 Feb 2018 01:25:45 +0900 (JST)
Subject: [ruby-changes:50325] nagachika:r62440 (ruby_2_4): merge revision(s) 59983, 59984: [Backport #10222] [Backport #14372] [Backport #14424]

nagachika	2018-02-17 01:25:40 +0900 (Sat, 17 Feb 2018)

  New Revision: 62440

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=62440

  Log:
    merge revision(s) 59983,59984: [Backport #10222] [Backport #14372] [Backport #14424]
    
    file.c: rb_check_realpath
    
    * file.c (rb_check_realpath): returns real path which has no
      symbolic links.  similar to rb_realpath except for returning
      Qnil if any parts did not exist.
    
    load.c: real path to load
    
    * load.c (rb_construct_expanded_load_path): expand load paths to
      real paths to get rid of duplicate loading from symbolic-linked
      directories.  [Feature #10222]

  Modified directories:
    branches/ruby_2_4/
  Modified files:
    branches/ruby_2_4/file.c
    branches/ruby_2_4/internal.h
    branches/ruby_2_4/load.c
    branches/ruby_2_4/test/ruby/test_exception.rb
    branches/ruby_2_4/test/ruby/test_require.rb
    branches/ruby_2_4/version.h
Index: ruby_2_4/file.c
===================================================================
--- ruby_2_4/file.c	(revision 62439)
+++ ruby_2_4/file.c	(revision 62440)
@@ -3757,8 +3757,29 @@ rb_file_s_absolute_path(int argc, const https://github.com/ruby/ruby/blob/trunk/ruby_2_4/file.c#L3757
     return rb_file_absolute_path(argv[0], argc > 1 ? argv[1] : Qnil);
 }
 
-static void
-realpath_rec(long *prefixlenp, VALUE *resolvedp, const char *unresolved, VALUE loopcheck, int strict, int last)
+#ifdef __native_client__
+VALUE
+rb_realpath_internal(VALUE basedir, VALUE path, int strict)
+{
+    return path;
+}
+
+VALUE
+rb_check_realpath(VALUE basedir, VALUE path)
+{
+    return path;
+}
+#else
+enum rb_realpath_mode {
+    RB_REALPATH_CHECK,
+    RB_REALPATH_DIR,
+    RB_REALPATH_STRICT,
+    RB_REALPATH_MODE_MAX
+};
+
+static int
+realpath_rec(long *prefixlenp, VALUE *resolvedp, const char *unresolved,
+	     VALUE loopcheck, enum rb_realpath_mode mode, int last)
 {
     const char *pend = unresolved + strlen(unresolved);
     rb_encoding *enc = rb_enc_get(*resolvedp);
@@ -3799,6 +3820,10 @@ realpath_rec(long *prefixlenp, VALUE *re https://github.com/ruby/ruby/blob/trunk/ruby_2_4/file.c#L3820
             checkval = rb_hash_aref(loopcheck, testpath);
             if (!NIL_P(checkval)) {
                 if (checkval == ID2SYM(resolving)) {
+		    if (mode == RB_REALPATH_CHECK) {
+			errno = ELOOP;
+			return -1;
+		    }
                     rb_syserr_fail_path(ELOOP, testpath);
                 }
                 else {
@@ -3816,8 +3841,9 @@ realpath_rec(long *prefixlenp, VALUE *re https://github.com/ruby/ruby/blob/trunk/ruby_2_4/file.c#L3841
 #endif
                 if (ret == -1) {
 		    int e = errno;
+		    if (mode == RB_REALPATH_CHECK) return -1;
 		    if (e == ENOENT) {
-                        if (strict || !last || *unresolved_firstsep)
+			if (mode == RB_REALPATH_STRICT || !last || *unresolved_firstsep)
 			    rb_syserr_fail_path(e, testpath);
                         *resolvedp = testpath;
                         break;
@@ -3846,7 +3872,9 @@ realpath_rec(long *prefixlenp, VALUE *re https://github.com/ruby/ruby/blob/trunk/ruby_2_4/file.c#L3872
 			*resolvedp = link;
 			*prefixlenp = link_prefixlen;
 		    }
-		    realpath_rec(prefixlenp, resolvedp, link_names, loopcheck, strict, *unresolved_firstsep == '\0');
+		    if (realpath_rec(prefixlenp, resolvedp, link_names,
+				     loopcheck, mode, !*unresolved_firstsep))
+			return -1;
 		    RB_GC_GUARD(link_orig);
 		    rb_hash_aset(loopcheck, testpath, rb_str_dup_frozen(*resolvedp));
                 }
@@ -3860,17 +3888,11 @@ realpath_rec(long *prefixlenp, VALUE *re https://github.com/ruby/ruby/blob/trunk/ruby_2_4/file.c#L3888
             }
         }
     }
+    return 0;
 }
 
-#ifdef __native_client__
-VALUE
-rb_realpath_internal(VALUE basedir, VALUE path, int strict)
-{
-    return path;
-}
-#else
-VALUE
-rb_realpath_internal(VALUE basedir, VALUE path, int strict)
+static VALUE
+rb_check_realpath_internal(VALUE basedir, VALUE path, enum rb_realpath_mode mode)
 {
     long prefixlen;
     VALUE resolved;
@@ -3937,11 +3959,16 @@ rb_realpath_internal(VALUE basedir, VALU https://github.com/ruby/ruby/blob/trunk/ruby_2_4/file.c#L3959
     }
 
     loopcheck = rb_hash_new();
-    if (curdir_names)
-        realpath_rec(&prefixlen, &resolved, curdir_names, loopcheck, 1, 0);
-    if (basedir_names)
-        realpath_rec(&prefixlen, &resolved, basedir_names, loopcheck, 1, 0);
-    realpath_rec(&prefixlen, &resolved, path_names, loopcheck, strict, 1);
+    if (curdir_names) {
+	if (realpath_rec(&prefixlen, &resolved, curdir_names, loopcheck, mode, 0))
+	    return Qnil;
+    }
+    if (basedir_names) {
+	if (realpath_rec(&prefixlen, &resolved, basedir_names, loopcheck, mode, 0))
+	    return Qnil;
+    }
+    if (realpath_rec(&prefixlen, &resolved, path_names, loopcheck, mode, 1))
+	return Qnil;
 
     if (origenc != enc && rb_enc_str_asciionly_p(resolved))
 	rb_enc_associate(resolved, origenc);
@@ -3949,6 +3976,20 @@ rb_realpath_internal(VALUE basedir, VALU https://github.com/ruby/ruby/blob/trunk/ruby_2_4/file.c#L3976
     OBJ_TAINT(resolved);
     return resolved;
 }
+
+VALUE
+rb_realpath_internal(VALUE basedir, VALUE path, int strict)
+{
+    const enum rb_realpath_mode mode =
+	strict ? RB_REALPATH_STRICT : RB_REALPATH_DIR;
+    return rb_check_realpath_internal(basedir, path, mode);
+}
+
+VALUE
+rb_check_realpath(VALUE basedir, VALUE path)
+{
+    return rb_check_realpath_internal(basedir, path, RB_REALPATH_CHECK);
+}
 #endif
 
 /*
Index: ruby_2_4/test/ruby/test_require.rb
===================================================================
--- ruby_2_4/test/ruby/test_require.rb	(revision 62439)
+++ ruby_2_4/test/ruby/test_require.rb	(revision 62440)
@@ -809,4 +809,18 @@ class TestRequire < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/ruby_2_4/test/ruby/test_require.rb#L809
       end;
     end
   end
+
+  def test_symlink_load_path
+    Dir.mktmpdir {|tmp|
+      Dir.mkdir(File.join(tmp, "real"))
+      begin
+        File.symlink "real", File.join(tmp, "symlink")
+      rescue NotImplementedError, Errno::EACCES
+        skip "File.symlink is not implemented"
+      end
+      File.write(File.join(tmp, "real/a.rb"), "print __FILE__")
+      result = IO.popen([EnvUtil.rubybin, "-I#{tmp}/symlink", "-e", "require 'a.rb'"], &:read)
+      assert_operator(result, :end_with?, "/real/a.rb")
+    }
+  end
 end
Index: ruby_2_4/test/ruby/test_exception.rb
===================================================================
--- ruby_2_4/test/ruby/test_exception.rb	(revision 62439)
+++ ruby_2_4/test/ruby/test_exception.rb	(revision 62440)
@@ -983,7 +983,7 @@ $stderr = $stdout; raise "\x82\xa0"') do https://github.com/ruby/ruby/blob/trunk/ruby_2_4/test/ruby/test_exception.rb#L983
     path = nil
     Tempfile.create(%w[circular .rb]) do |t|
       begin
-        path = t.path
+        path = File.realpath(t.path)
         basename = File.basename(path)
         t.puts "require '#{basename}'"
         t.close
Index: ruby_2_4/internal.h
===================================================================
--- ruby_2_4/internal.h	(revision 62439)
+++ ruby_2_4/internal.h	(revision 62440)
@@ -1051,6 +1051,7 @@ void rb_mark_end_proc(void); https://github.com/ruby/ruby/blob/trunk/ruby_2_4/internal.h#L1051
 VALUE rb_home_dir_of(VALUE user, VALUE result);
 VALUE rb_default_home_dir(VALUE result);
 VALUE rb_realpath_internal(VALUE basedir, VALUE path, int strict);
+VALUE rb_check_realpath(VALUE basedir, VALUE path);
 void rb_file_const(const char*, VALUE);
 int rb_file_load_ok(const char *);
 VALUE rb_file_expand_path_fast(VALUE, VALUE);
Index: ruby_2_4/load.c
===================================================================
--- ruby_2_4/load.c	(revision 62439)
+++ ruby_2_4/load.c	(revision 62440)
@@ -85,7 +85,8 @@ rb_construct_expanded_load_path(enum exp https://github.com/ruby/ruby/blob/trunk/ruby_2_4/load.c#L85
 	if (is_string)
 	    rb_str_freeze(path);
 	as_str = rb_get_path_check_convert(path, as_str, level);
-	expanded_path = rb_file_expand_path_fast(as_str, Qnil);
+	expanded_path = rb_check_realpath(Qnil, as_str);
+	if (NIL_P(expanded_path)) expanded_path = as_str;
 	rb_str_freeze(expanded_path);
 	rb_ary_push(ary, rb_fstring(expanded_path));
     }
Index: ruby_2_4/version.h
===================================================================
--- ruby_2_4/version.h	(revision 62439)
+++ ruby_2_4/version.h	(revision 62440)
@@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_4/version.h#L1
 #define RUBY_VERSION "2.4.4"
 #define RUBY_RELEASE_DATE "2018-02-17"
-#define RUBY_PATCHLEVEL 238
+#define RUBY_PATCHLEVEL 239
 
 #define RUBY_RELEASE_YEAR 2018
 #define RUBY_RELEASE_MONTH 2
Index: ruby_2_4
===================================================================
--- ruby_2_4	(revision 62439)
+++ ruby_2_4	(revision 62440)

Property changes on: ruby_2_4
___________________________________________________________________
Modified: svn:mergeinfo
## -0,0 +0,1 ##
   Merged /trunk:r59983-59984

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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