From 720a15b7be589483e5977ef971b2407f2f6a1961 Mon Sep 17 00:00:00 2001 From: nobu Date: Thu, 8 Jun 2017 01:58:44 +0000 Subject: 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 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59040 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- dir.c | 33 ++++++++++++++++++++++++--------- file.c | 34 ++++++++++++++++++++++++---------- internal.h | 3 +++ 3 files changed, 51 insertions(+), 19 deletions(-) diff --git a/dir.c b/dir.c index 25e6a9fccb..3f25bc576d 100644 --- a/dir.c +++ b/dir.c @@ -1082,30 +1082,25 @@ dir_s_chdir(int argc, VALUE *argv, VALUE obj) } VALUE -rb_dir_getwd(void) +rb_dir_getwd_ospath(void) { char *path; VALUE cwd; - rb_encoding *fs = rb_filesystem_encoding(); - int fsenc = rb_enc_to_index(fs); VALUE path_guard; #undef RUBY_UNTYPED_DATA_WARNING #define RUBY_UNTYPED_DATA_WARNING 0 - if (fsenc == ENCINDEX_US_ASCII) fsenc = ENCINDEX_ASCII; path_guard = Data_Wrap_Struct((VALUE)0, NULL, RUBY_DEFAULT_FREE, NULL); path = my_getcwd(); DATA_PTR(path_guard) = path; #ifdef _WIN32 - cwd = rb_str_conv_enc(rb_utf8_str_new_cstr(path), NULL, fs); -#else -#ifdef __APPLE__ + cwd = rb_utf8_str_new_cstr(path); + OBJ_TAINT(cwd); +#elif defined __APPLE__ cwd = rb_str_normalize_ospath(path, strlen(path)); OBJ_TAINT(cwd); #else cwd = rb_tainted_str_new2(path); -#endif - rb_enc_associate_index(cwd, fsenc); #endif DATA_PTR(path_guard) = 0; @@ -1113,6 +1108,26 @@ rb_dir_getwd(void) return cwd; } +VALUE +rb_dir_getwd(void) +{ + rb_encoding *fs = rb_filesystem_encoding(); + int fsenc = rb_enc_to_index(fs); + VALUE cwd = rb_dir_getwd_ospath(); + + switch (fsenc) { + case ENCINDEX_US_ASCII: + fsenc = ENCINDEX_ASCII; + case ENCINDEX_ASCII: + break; +#if defined _WIN32 || defined __APPLE__ + default: + return rb_str_conv_enc(cwd, NULL, fs); +#endif + } + return rb_enc_associate_index(cwd, fsenc); +} + /* * call-seq: * Dir.getwd -> string diff --git a/file.c b/file.c index 31e5971894..ce367fd902 100644 --- a/file.c +++ b/file.c @@ -127,6 +127,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) { @@ -3811,11 +3819,10 @@ realpath_rec(long *prefixlenp, VALUE *resolvedp, const char *unresolved, VALUE l 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; @@ -3890,9 +3897,12 @@ rb_realpath_internal(VALUE basedir, VALUE path, int strict) 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) { @@ -3909,7 +3919,7 @@ rb_realpath_internal(VALUE basedir, VALUE path, int strict) } } - 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); @@ -3917,7 +3927,6 @@ rb_realpath_internal(VALUE basedir, VALUE path, int strict) 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; @@ -3932,7 +3941,6 @@ rb_realpath_internal(VALUE basedir, VALUE path, int strict) } #endif - origenc = enc; switch (rb_enc_to_index(enc)) { case ENCINDEX_ASCII: case ENCINDEX_US_ASCII: @@ -3946,8 +3954,14 @@ rb_realpath_internal(VALUE basedir, VALUE path, int strict) 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); + 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; diff --git a/internal.h b/internal.h index d034004f76..cc1d97534b 100644 --- a/internal.h +++ b/internal.h @@ -1088,6 +1088,9 @@ void ruby_register_rollback_func_for_ensure(VALUE (*ensure_func)(ANYARGS), VALUE /* debug.c */ PRINTF_ARGS(void ruby_debug_printf(const char*, ...), 1, 2); +/* dir.c */ +VALUE rb_dir_getwd_ospath(void); + /* dmyext.c */ void Init_enc(void); void Init_ext(void); -- cgit v1.2.3