load.c: search in OS path encoding

* load.c (rb_load_internal): use rb_load_file_str() to keep path
  encoding.
* load.c (rb_require_safe): search in OS path encoding for Windows.
* ruby.c (rb_load_file_str): load file with keeping path encoding.
* win32/file.c (rb_file_load_ok): use WCHAR type API assuming incoming
  path is encoded in UTF-8.  [ruby-core:56136] [Bug #8676]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42183 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2013-07-26 04:04:23 +00:00
parent 2c181b6d1a
commit 8948280c67
6 changed files with 42 additions and 10 deletions

View File

@ -1,4 +1,14 @@
Fri Jul 26 13:01:57 2013 Nobuyoshi Nakada <nobu@ruby-lang.org> Fri Jul 26 13:04:15 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
* load.c (rb_load_internal): use rb_load_file_str() to keep path
encoding.
* load.c (rb_require_safe): search in OS path encoding for Windows.
* ruby.c (rb_load_file_str): load file with keeping path encoding.
* win32/file.c (rb_file_load_ok): use WCHAR type API assuming incoming
path is encoded in UTF-8. [ruby-core:56136] [Bug #8676]
* file.c (rb_str_encode_ospath): simplify using rb_str_conv_enc(). * file.c (rb_str_encode_ospath): simplify using rb_str_conv_enc().

View File

@ -644,6 +644,7 @@ int rb_reg_options(VALUE);
RUBY_EXTERN VALUE rb_argv0; RUBY_EXTERN VALUE rb_argv0;
VALUE rb_get_argv(void); VALUE rb_get_argv(void);
void *rb_load_file(const char*); void *rb_load_file(const char*);
void *rb_load_file_str(VALUE);
/* signal.c */ /* signal.c */
VALUE rb_f_kill(int, VALUE*); VALUE rb_f_kill(int, VALUE*);
#ifdef POSIX_SIGNAL #ifdef POSIX_SIGNAL

5
load.c
View File

@ -591,7 +591,7 @@ rb_load_internal(VALUE fname, int wrap)
VALUE iseq; VALUE iseq;
th->mild_compile_error++; th->mild_compile_error++;
node = (NODE *)rb_load_file(RSTRING_PTR(fname)); node = (NODE *)rb_load_file_str(fname);
loaded = TRUE; loaded = TRUE;
iseq = rb_iseq_new_top(node, rb_str_new2("<top (required)>"), fname, rb_realpath_internal(Qnil, fname, 1), Qfalse); iseq = rb_iseq_new_top(node, rb_str_new2("<top (required)>"), fname, rb_realpath_internal(Qnil, fname, 1), Qfalse);
th->mild_compile_error--; th->mild_compile_error--;
@ -941,7 +941,8 @@ rb_require_safe(VALUE fname, int safe)
rb_sourceline()); rb_sourceline());
} }
found = search_required(fname, &path, safe); path = rb_str_encode_ospath(fname);
found = search_required(path, &path, safe);
if (RUBY_DTRACE_FIND_REQUIRE_RETURN_ENABLED()) { if (RUBY_DTRACE_FIND_REQUIRE_RETURN_ENABLED()) {
RUBY_DTRACE_FIND_REQUIRE_RETURN(StringValuePtr(fname), RUBY_DTRACE_FIND_REQUIRE_RETURN(StringValuePtr(fname),

8
ruby.c
View File

@ -1768,8 +1768,14 @@ load_file(VALUE parser, VALUE fname, int script, struct cmdline_options *opt)
void * void *
rb_load_file(const char *fname) rb_load_file(const char *fname)
{ {
struct cmdline_options opt;
VALUE fname_v = rb_str_new_cstr(fname); VALUE fname_v = rb_str_new_cstr(fname);
return rb_load_file_str(fname_v);
}
void *
rb_load_file_str(VALUE fname_v)
{
struct cmdline_options opt;
return load_file(rb_parser_new(), fname_v, 0, cmdline_options_init(&opt)); return load_file(rb_parser_new(), fname_v, 0, cmdline_options_init(&opt));
} }

View File

@ -61,10 +61,17 @@ class TestRequire < Test::Unit::TestCase
def test_require_nonascii_path def test_require_nonascii_path
bug8165 = '[ruby-core:53733] [Bug #8165]' bug8165 = '[ruby-core:53733] [Bug #8165]'
encoding = /mswin|mingw/ =~ RUBY_PLATFORM ? 'filesystem' : 'UTF-8' encoding = 'filesystem'
assert_require_nonascii_path(encoding, bug8165) assert_require_nonascii_path(encoding, bug8165)
end end
def test_require_nonascii_path_utf8
bug8676 = '[ruby-core:56136] [Bug #8676]'
encoding = Encoding::UTF_8
return if Encoding.find('filesystem') == encoding
assert_require_nonascii_path(encoding, bug8676)
end
def assert_require_nonascii_path(encoding, bug) def assert_require_nonascii_path(encoding, bug)
Dir.mktmpdir {|tmp| Dir.mktmpdir {|tmp|
dir = "\u3042" * 5 dir = "\u3042" * 5

View File

@ -681,16 +681,22 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
int int
rb_file_load_ok(const char *path) rb_file_load_ok(const char *path)
{ {
DWORD attr;
int ret = 1; int ret = 1;
DWORD attr = GetFileAttributes(path); size_t len;
wchar_t* wpath;
convert_mb_to_wchar(path, &wpath, &len, CP_UTF8);
attr = GetFileAttributesW(wpath);
if (attr == INVALID_FILE_ATTRIBUTES || if (attr == INVALID_FILE_ATTRIBUTES ||
attr & FILE_ATTRIBUTE_DIRECTORY) { (attr & FILE_ATTRIBUTE_DIRECTORY)) {
ret = 0; ret = 0;
} }
else { else {
HANDLE h = CreateFile(path, GENERIC_READ, HANDLE h = CreateFileW(wpath, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (h != INVALID_HANDLE_VALUE) { if (h != INVALID_HANDLE_VALUE) {
CloseHandle(h); CloseHandle(h);
} }
@ -698,6 +704,7 @@ rb_file_load_ok(const char *path)
ret = 0; ret = 0;
} }
} }
xfree(wpath);
return ret; return ret;
} }