summaryrefslogtreecommitdiff
path: root/file.c
diff options
context:
space:
mode:
authornagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-03-16 17:34:44 +0000
committernagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-03-16 17:34:44 +0000
commit2368dbdfa3c438b614a4727bde7cacac2d0a87a9 (patch)
treea3580abe631e47b8fc161eb5085587023cf19bfa /file.c
parent3ca42c0435512e44f4662152afa62100be968c8f (diff)
merge revision(s) 58745,58780,59040,60743: [Backport #13863]
rb_w32_ugetcwd: UTF-8 version getcwd * dir.c (rb_dir_getwd): convert from UTF-8. * win32/win32.c (w32_getcwd): codepage aware getcwd using GetCurrentDirectoryW. potential memory leak * dir.c (rb_dir_getwd): get rid of potential memory leak. * util.c (ruby_getcwd): ditto. file.c: realpath in OS path encoding * dir.c (rb_dir_getwd_ospath): return cwd path in the OS path encoding. * file.c (rb_realpath_internal): work in the OS path encoding load.c: cwd encoding * load.c (rb_get_expanded_load_path): save cwd cache in OS path encoding, to get rid of unnecessary conversion and infinite loading when it needs encoding conversion. [ruby-dev:50221] [Bug #13863] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_4@62784 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'file.c')
-rw-r--r--file.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/file.c b/file.c
index 0e67654da2..43040787d0 100644
--- a/file.c
+++ b/file.c
@@ -126,6 +126,14 @@ int flock(int, int);
#define STAT(p, s) stat((p), (s))
#endif
+#if defined _WIN32 || defined __APPLE__
+# define USE_OSPATH 1
+# define TO_OSPATH(str) rb_str_encode_ospath(str)
+#else
+# define USE_OSPATH 0
+# define TO_OSPATH(str) (str)
+#endif
+
VALUE rb_cFile;
VALUE rb_mFileTest;
VALUE rb_cStat;
@@ -222,7 +230,7 @@ rb_get_path(VALUE obj)
VALUE
rb_str_encode_ospath(VALUE path)
{
-#if defined _WIN32 || defined __APPLE__
+#if USE_OSPATH
int encidx = ENCODING_GET(path);
#ifdef _WIN32
if (encidx == ENCINDEX_ASCII) {
@@ -3833,11 +3841,10 @@ realpath_rec(long *prefixlenp, VALUE *resolvedp, const char *unresolved,
else {
struct stat sbuf;
int ret;
- VALUE testpath2 = rb_str_encode_ospath(testpath);
#ifdef __native_client__
- ret = stat(RSTRING_PTR(testpath2), &sbuf);
+ ret = stat(RSTRING_PTR(testpath), &sbuf);
#else
- ret = lstat(RSTRING_PTR(testpath2), &sbuf);
+ ret = lstat(RSTRING_PTR(testpath), &sbuf);
#endif
if (ret == -1) {
int e = errno;
@@ -3909,9 +3916,12 @@ rb_check_realpath_internal(VALUE basedir, VALUE path, enum rb_realpath_mode mode
if (!NIL_P(basedir)) {
FilePathValue(basedir);
- basedir = rb_str_dup_frozen(basedir);
+ basedir = TO_OSPATH(rb_str_dup_frozen(basedir));
}
+ enc = rb_enc_get(unresolved_path);
+ origenc = enc;
+ unresolved_path = TO_OSPATH(unresolved_path);
RSTRING_GETMEM(unresolved_path, ptr, len);
path_names = skipprefixroot(ptr, ptr + len, rb_enc_get(unresolved_path));
if (ptr != path_names) {
@@ -3928,7 +3938,7 @@ rb_check_realpath_internal(VALUE basedir, VALUE path, enum rb_realpath_mode mode
}
}
- curdir = rb_dir_getwd();
+ curdir = rb_dir_getwd_ospath();
RSTRING_GETMEM(curdir, ptr, len);
curdir_names = skipprefixroot(ptr, ptr + len, rb_enc_get(curdir));
resolved = rb_str_subseq(curdir, 0, curdir_names - ptr);
@@ -3936,7 +3946,6 @@ rb_check_realpath_internal(VALUE basedir, VALUE path, enum rb_realpath_mode mode
root_found:
RSTRING_GETMEM(resolved, prefixptr, prefixlen);
pend = prefixptr + prefixlen;
- enc = rb_enc_get(resolved);
ptr = chompdirsep(prefixptr, pend, enc);
if (ptr < pend) {
prefixlen = ++ptr - prefixptr;
@@ -3951,7 +3960,6 @@ rb_check_realpath_internal(VALUE basedir, VALUE path, enum rb_realpath_mode mode
}
#endif
- origenc = enc;
switch (rb_enc_to_index(enc)) {
case ENCINDEX_ASCII:
case ENCINDEX_US_ASCII:
@@ -3970,8 +3978,14 @@ rb_check_realpath_internal(VALUE basedir, VALUE path, enum rb_realpath_mode mode
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);
+ if (origenc != rb_enc_get(resolved)) {
+ if (rb_enc_str_asciionly_p(resolved)) {
+ rb_enc_associate(resolved, origenc);
+ }
+ else {
+ resolved = rb_str_conv_enc(resolved, NULL, origenc);
+ }
+ }
OBJ_TAINT(resolved);
return resolved;