aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2021-01-14 00:14:11 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2021-01-15 17:46:48 +0900
commit0d57d59933fb7b826bd0e20d84ed7f6d6636ac90 (patch)
tree67f747a4495ca881515145141050d8290a5fdb7d
parente09094546a19d6b62b3e21d0b061b103cf21f760 (diff)
downloadruby-0d57d59933fb7b826bd0e20d84ed7f6d6636ac90.tar.gz
Keep encoding in the result of File.expand_path [Bug #17517]
-rw-r--r--file.c26
-rw-r--r--test/ruby/test_file_exhaustive.rb2
2 files changed, 22 insertions, 6 deletions
diff --git a/file.c b/file.c
index 0c599b0895..89867d13c4 100644
--- a/file.c
+++ b/file.c
@@ -3467,6 +3467,20 @@ rb_enc_path_end(const char *path, const char *end, rb_encoding *enc)
return chompdirsep(path, end, enc);
}
+static rb_encoding *
+fs_enc_check(VALUE path1, VALUE path2)
+{
+ rb_encoding *enc = rb_enc_check(path1, path2);
+ int encidx = rb_enc_to_index(enc);
+ if (encidx == ENCINDEX_US_ASCII) {
+ encidx = rb_enc_get_index(path1);
+ if (encidx == ENCINDEX_US_ASCII)
+ encidx = rb_enc_get_index(path2);
+ enc = rb_enc_from_index(encidx);
+ }
+ return enc;
+}
+
#if USE_NTFS
static char *
ntfs_tail(const char *path, const char *end, rb_encoding *enc)
@@ -3667,7 +3681,7 @@ append_fspath(VALUE result, VALUE fname, char *dir, rb_encoding **enc, rb_encodi
size_t dirlen = strlen(dir), buflen = rb_str_capacity(result);
if (NORMALIZE_UTF8PATH || *enc != fsenc) {
- rb_encoding *direnc = rb_enc_check(fname, dirname = ospath_new(dir, dirlen, fsenc));
+ rb_encoding *direnc = fs_enc_check(fname, dirname = ospath_new(dir, dirlen, fsenc));
if (direnc != fsenc) {
dirname = rb_str_conv_enc(dirname, fsenc, direnc);
RSTRING_GETMEM(dirname, cwdp, dirlen);
@@ -3763,7 +3777,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
p = e;
}
else {
- rb_enc_associate(result, enc = rb_enc_check(result, fname));
+ rb_enc_associate(result, enc = fs_enc_check(result, fname));
p = pend;
}
p = chompdirsep(skiproot(buf, p, enc), p, enc);
@@ -3774,7 +3788,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
else if (!rb_is_absolute_path(s)) {
if (!NIL_P(dname)) {
rb_file_expand_path_internal(dname, Qnil, abs_mode, long_name, result);
- rb_enc_associate(result, rb_enc_check(result, fname));
+ rb_enc_associate(result, fs_enc_check(result, fname));
BUFINIT();
p = pend;
}
@@ -3802,7 +3816,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
BUFCHECK(bdiff >= buflen);
memset(buf, '/', len);
rb_str_set_len(result, len);
- rb_enc_associate(result, rb_enc_check(result, fname));
+ rb_enc_associate(result, fs_enc_check(result, fname));
}
if (p > buf && p[-1] == '/')
--p;
@@ -4263,7 +4277,7 @@ realpath_rec(long *prefixlenp, VALUE *resolvedp, const char *unresolved, VALUE f
rb_encoding *tmpenc, *linkenc = rb_enc_get(link);
link_orig = link;
link = rb_str_subseq(link, 0, link_prefixlen);
- tmpenc = rb_enc_check(*resolvedp, link);
+ tmpenc = fs_enc_check(*resolvedp, link);
if (tmpenc != linkenc) link = rb_str_conv_enc(link, linkenc, tmpenc);
*resolvedp = link;
*prefixlenp = link_prefixlen;
@@ -4937,7 +4951,7 @@ rb_file_join(VALUE ary)
rb_str_cat(result, "/", 1);
}
}
- enc = rb_enc_check(result, tmp);
+ enc = fs_enc_check(result, tmp);
rb_str_buf_append(result, tmp);
rb_enc_associate(result, enc);
}
diff --git a/test/ruby/test_file_exhaustive.rb b/test/ruby/test_file_exhaustive.rb
index ac11e0cc85..b966cc690c 100644
--- a/test/ruby/test_file_exhaustive.rb
+++ b/test/ruby/test_file_exhaustive.rb
@@ -880,6 +880,8 @@ class TestFileExhaustive < Test::Unit::TestCase
assert_equal("#{Dir.pwd}/#{path}", File.expand_path(path))
assert_incompatible_encoding {|d| File.expand_path(d)}
+
+ assert_equal(Encoding::UTF_8, File.expand_path("foo", "#{drive}/").encoding)
end
def test_expand_path_encoding_filesystem