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/