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

ruby-changes:39657

From: nobu <ko1@a...>
Date: Wed, 2 Sep 2015 16:58:42 +0900 (JST)
Subject: [ruby-changes:39657] nobu:r51738 (trunk): file.c: use filesystem encoding

nobu	2015-09-02 16:58:24 +0900 (Wed, 02 Sep 2015)

  New Revision: 51738

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

  Log:
    file.c: use filesystem encoding
    
    * file.c (rb_realpath_internal): use filesystem encoding if the
      argument is in ASCII encodings.
    * win32/file.c (rb_readlink): needs the result encoding.

  Modified files:
    trunk/ChangeLog
    trunk/file.c
    trunk/test/ruby/test_file.rb
    trunk/win32/file.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 51737)
+++ ChangeLog	(revision 51738)
@@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Wed Sep  2 16:58:21 2015  Nobuyoshi Nakada  <nobu@r...>
+
+	* file.c (rb_realpath_internal): use filesystem encoding if the
+	  argument is in ASCII encodings.
+
+	* win32/file.c (rb_readlink): needs the result encoding.
+
 Tue Sep  1 18:37:15 2015  Koichi Sasada  <ko1@a...>
 
 	* test/thread/test_queue.rb: catch up last commit.
Index: win32/file.c
===================================================================
--- win32/file.c	(revision 51737)
+++ win32/file.c	(revision 51738)
@@ -660,7 +660,7 @@ rb_file_expand_path_internal(VALUE fname https://github.com/ruby/ruby/blob/trunk/win32/file.c#L660
 }
 
 VALUE
-rb_readlink(VALUE path)
+rb_readlink(VALUE path, rb_encoding *resultenc)
 {
     DWORD len;
     VALUE wtmp = 0, wpathbuf, str;
@@ -692,7 +692,7 @@ rb_readlink(VALUE path) https://github.com/ruby/ruby/blob/trunk/win32/file.c#L692
 	ALLOCV_END(wtmp);
 	rb_syserr_fail_path(rb_w32_map_errno(e), path);
     }
-    enc = rb_filesystem_encoding();
+    enc = resultenc;
     cp = path_cp = code_page(enc);
     if (cp == INVALID_CODE_PAGE) cp = CP_UTF8;
     str = append_wstr(rb_enc_str_new(0, 0, enc), wbuf, len, cp, path_cp, enc);
Index: test/ruby/test_file.rb
===================================================================
--- test/ruby/test_file.rb	(revision 51737)
+++ test/ruby/test_file.rb	(revision 51738)
@@ -258,6 +258,26 @@ class TestFile < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_file.rb#L258
     }
   end
 
+  def test_realpath_encoding
+    fsenc = Encoding.find("filesystem")
+    nonascii = "\u{0391 0410 0531 10A0 05d0 2C00 3042}"
+    tst = "A"
+    nonascii.each_char {|c| tst << c.encode(fsenc) rescue nil}
+    Dir.mktmpdir('rubytest-realpath') {|tmpdir|
+      realdir = File.realpath(tmpdir)
+      open(File.join(tmpdir, tst), "w") {}
+      a = File.join(tmpdir, "a")
+      File.symlink(tst, a)
+      assert_equal(File.join(realdir, tst), File.realpath(a))
+      File.unlink(a)
+
+      tst = "A" + nonascii
+      open(File.join(tmpdir, tst), "w") {}
+      File.symlink(tst, a)
+      assert_equal(File.join(realdir, tst), File.realpath(a.encode("UTF-8")))
+    }
+  end
+
   def test_realdirpath
     Dir.mktmpdir('rubytest-realdirpath') {|tmpdir|
       realdir = File.realpath(tmpdir)
Index: file.c
===================================================================
--- file.c	(revision 51737)
+++ file.c	(revision 51738)
@@ -2786,7 +2786,7 @@ rb_file_s_symlink(VALUE klass, VALUE fro https://github.com/ruby/ruby/blob/trunk/file.c#L2786
 #endif
 
 #ifdef HAVE_READLINK
-VALUE rb_readlink(VALUE path);
+VALUE rb_readlink(VALUE path, rb_encoding *enc);
 
 /*
  *  call-seq:
@@ -2802,12 +2802,12 @@ VALUE rb_readlink(VALUE path); https://github.com/ruby/ruby/blob/trunk/file.c#L2802
 static VALUE
 rb_file_s_readlink(VALUE klass, VALUE path)
 {
-    return rb_readlink(path);
+    return rb_readlink(path, rb_filesystem_encoding());
 }
 
 #ifndef _WIN32
 VALUE
-rb_readlink(VALUE path)
+rb_readlink(VALUE path, rb_encoding *enc)
 {
     int size = 100;
     ssize_t rv;
@@ -2815,7 +2815,7 @@ rb_readlink(VALUE path) https://github.com/ruby/ruby/blob/trunk/file.c#L2815
 
     FilePathValue(path);
     path = rb_str_encode_ospath(path);
-    v = rb_enc_str_new(0, size, rb_filesystem_encoding());
+    v = rb_enc_str_new(0, size, enc);
     while ((rv = readlink(RSTRING_PTR(path), RSTRING_PTR(v), size)) == size
 #ifdef _AIX
 	    || (rv < 0 && errno == ERANGE) /* quirky behavior of GPFS */
@@ -3810,7 +3810,7 @@ realpath_rec(long *prefixlenp, VALUE *re https://github.com/ruby/ruby/blob/trunk/file.c#L3810
 		    const char *link_prefix, *link_names;
                     long link_prefixlen;
                     rb_hash_aset(loopcheck, testpath, ID2SYM(resolving));
-		    link = rb_readlink(testpath);
+		    link = rb_readlink(testpath, enc);
                     link_prefix = RSTRING_PTR(link);
 		    link_names = skipprefixroot(link_prefix, link_prefix + RSTRING_LEN(link), rb_enc_get(link));
 		    link_prefixlen = link_names - link_prefix;
@@ -3855,7 +3855,7 @@ rb_realpath_internal(VALUE basedir, VALU https://github.com/ruby/ruby/blob/trunk/file.c#L3855
     VALUE loopcheck;
     volatile VALUE curdir = Qnil;
 
-    rb_encoding *enc;
+    rb_encoding *enc, *origenc;
     char *path_names = NULL, *basedir_names = NULL, *curdir_names = NULL;
     char *ptr, *prefixptr = NULL, *pend;
     long len;
@@ -3907,6 +3907,13 @@ rb_realpath_internal(VALUE basedir, VALU https://github.com/ruby/ruby/blob/trunk/file.c#L3907
     }
 #endif
 
+    origenc = enc;
+    switch (rb_enc_to_index(enc)) {
+      case ENCINDEX_ASCII:
+      case ENCINDEX_US_ASCII:
+	rb_enc_associate(resolved, rb_filesystem_encoding());
+    }
+
     loopcheck = rb_hash_new();
     if (curdir_names)
         realpath_rec(&prefixlen, &resolved, curdir_names, loopcheck, 1, 0);
@@ -3914,6 +3921,9 @@ rb_realpath_internal(VALUE basedir, VALU https://github.com/ruby/ruby/blob/trunk/file.c#L3921
         realpath_rec(&prefixlen, &resolved, basedir_names, loopcheck, 1, 0);
     realpath_rec(&prefixlen, &resolved, path_names, loopcheck, strict, 1);
 
+    if (origenc != enc && rb_enc_str_asciionly_p(resolved))
+	rb_enc_associate(resolved, origenc);
+
     OBJ_TAINT(resolved);
     return resolved;
 }

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

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