ruby-changes:28197
From: nagachika <ko1@a...>
Date: Fri, 12 Apr 2013 01:48:11 +0900 (JST)
Subject: [ruby-changes:28197] nagachika:r40249 (ruby_2_0_0): merge revision(s) 39697,39701,39716,39740,39751: [Backport #8069]
nagachika 2013-04-12 01:47:45 +0900 (Fri, 12 Apr 2013) New Revision: 40249 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=40249 Log: merge revision(s) 39697,39701,39716,39740,39751: [Backport #8069] * win32/file.c (rb_file_expand_path_internal): Expand home directory when used as second parameter (dir_string). [ruby-core:53168] [Bug #8034] * test/ruby/test_file_exhaustive.rb: add test to verify. * win32/file.c (get_user_from_path): add internal function that retrieves username from supplied path (refactored). * win32/file.c (rb_file_expand_path_internal): refactor expansion of user home to use get_user_from_path and cover dir_string corner cases. [ruby-core:53168] [Bug #8034] Modified directories: branches/ruby_2_0_0/ Modified files: branches/ruby_2_0_0/ChangeLog branches/ruby_2_0_0/test/ruby/test_file_exhaustive.rb branches/ruby_2_0_0/version.h branches/ruby_2_0_0/win32/file.c Index: ruby_2_0_0/ChangeLog =================================================================== --- ruby_2_0_0/ChangeLog (revision 40248) +++ ruby_2_0_0/ChangeLog (revision 40249) @@ -1,3 +1,17 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/ChangeLog#L1 +Fri Apr 12 01:28:46 2013 Luis Lavena <luislavena@g...> + + * win32/file.c (get_user_from_path): add internal function that retrieves + username from supplied path (refactored). + * win32/file.c (rb_file_expand_path_internal): refactor expansion of user + home to use get_user_from_path and cover dir_string corner cases. + [ruby-core:53168] [Bug #8034] + +Fri Apr 12 01:28:46 2013 Luis Lavena <luislavena@g...> + + * win32/file.c (rb_file_expand_path_internal): Expand home directory when + used as second parameter (dir_string). [ruby-core:53168] [Bug #8034] + * test/ruby/test_file_exhaustive.rb: add test to verify. + Mon Apr 8 00:10:59 2013 Narihiro Nakamura <authornari@g...> * gc.c: Fix unlimited memory growth with large values of Index: ruby_2_0_0/win32/file.c =================================================================== --- ruby_2_0_0/win32/file.c (revision 40248) +++ ruby_2_0_0/win32/file.c (revision 40249) @@ -317,13 +317,45 @@ replace_to_long_name(wchar_t **wfullpath https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/win32/file.c#L317 return size; } +static inline VALUE +get_user_from_path(wchar_t **wpath, int offset, UINT cp, UINT path_cp, rb_encoding *path_encoding) +{ + VALUE result, tmp; + wchar_t *wuser = *wpath + offset; + wchar_t *pos = wuser; + char *user; + size_t size; + + while (!IS_DIR_SEPARATOR_P(*pos) && *pos != '\0') + pos++; + + *pos = '\0'; + convert_wchar_to_mb(wuser, &user, &size, cp); + + /* convert to VALUE and set the path encoding */ + if (path_cp == INVALID_CODE_PAGE) { + tmp = rb_enc_str_new(user, size, rb_utf8_encoding()); + result = rb_str_encode(tmp, rb_enc_from_encoding(path_encoding), 0, Qnil); + rb_str_resize(tmp, 0); + } + else { + result = rb_enc_str_new(user, size, path_encoding); + } + + if (user) + xfree(user); + + return result; +} + VALUE rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_name, VALUE result) { size_t size = 0, wpath_len = 0, wdir_len = 0, whome_len = 0; size_t buffer_len = 0; char *fullpath = NULL; - wchar_t *wfullpath = NULL, *wpath = NULL, *wpath_pos = NULL, *wdir = NULL; + wchar_t *wfullpath = NULL, *wpath = NULL, *wpath_pos = NULL; + wchar_t *wdir = NULL, *wdir_pos = NULL; wchar_t *whome = NULL, *buffer = NULL, *buffer_pos = NULL; UINT path_cp, cp; VALUE path = fname, dir = dname; @@ -404,32 +436,10 @@ rb_file_expand_path_internal(VALUE fname https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/win32/file.c#L436 } } else if (abs_mode == 0 && wpath_len >= 2 && wpath_pos[0] == L'~') { - wchar_t *wuser = wpath_pos + 1; - wchar_t *pos = wuser; - char *user; - - /* tainted if expanding '~' */ - tainted = 1; - - while (!IS_DIR_SEPARATOR_P(*pos) && *pos != '\0') - pos++; - - *pos = '\0'; - convert_wchar_to_mb(wuser, &user, &size, cp); + result = get_user_from_path(&wpath_pos, 1, cp, path_cp, path_encoding); - /* convert to VALUE and set the path encoding */ - if (path_cp == INVALID_CODE_PAGE) { - VALUE tmp = rb_enc_str_new(user, size, rb_utf8_encoding()); - result = rb_str_encode(tmp, rb_enc_from_encoding(path_encoding), 0, Qnil); - rb_str_resize(tmp, 0); - } - else { - result = rb_enc_str_new(user, size, path_encoding); - } - - xfree(wpath); - if (user) - xfree(user); + if (wpath) + xfree(wpath); rb_raise(rb_eArgError, "can't find user %s", StringValuePtr(result)); } @@ -442,9 +452,38 @@ rb_file_expand_path_internal(VALUE fname https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/win32/file.c#L452 } /* convert char * to wchar_t */ - convert_mb_to_wchar(dir, &wdir, NULL, &wdir_len, cp); + convert_mb_to_wchar(dir, &wdir, &wdir_pos, &wdir_len, cp); + + if (abs_mode == 0 && wdir_len > 0 && wdir_pos[0] == L'~' && + (wdir_len == 1 || IS_DIR_SEPARATOR_P(wdir_pos[1]))) { + /* tainted if expanding '~' */ + tainted = 1; - if (wdir_len >= 2 && wdir[1] == L':') { + whome = home_dir(); + if (whome == NULL) { + xfree(wpath); + xfree(wdir); + rb_raise(rb_eArgError, "couldn't find HOME environment -- expanding `~'"); + } + whome_len = wcslen(whome); + + if (PathIsRelativeW(whome) && !(whome_len >= 2 && IS_DIR_UNC_P(whome))) { + xfree(wpath); + xfree(wdir); + rb_raise(rb_eArgError, "non-absolute home"); + } + + /* exclude ~ from the result */ + wdir_pos++; + wdir_len--; + + /* exclude separator if present */ + if (wdir_len && IS_DIR_SEPARATOR_P(wdir_pos[0])) { + wdir_pos++; + wdir_len--; + } + } + else if (wdir_len >= 2 && wdir[1] == L':') { dir_drive = wdir[0]; if (wpath_len && IS_DIR_SEPARATOR_P(wpath_pos[0])) { wdir_len = 2; @@ -466,6 +505,16 @@ rb_file_expand_path_internal(VALUE fname https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/win32/file.c#L505 wdir_len = pos - 1; } } + else if (abs_mode == 0 && wdir_len >= 2 && wdir_pos[0] == L'~') { + result = get_user_from_path(&wdir_pos, 1, cp, path_cp, path_encoding); + if (wpath) + xfree(wpath); + + if (wdir) + xfree(wdir); + + rb_raise(rb_eArgError, "can't find user %s", StringValuePtr(result)); + } } /* determine if we ignore dir or not */ @@ -515,7 +564,7 @@ rb_file_expand_path_internal(VALUE fname https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/win32/file.c#L564 if (!tainted && OBJ_TAINTED(dir)) tainted = 1; - wcsncpy(buffer_pos, wdir, wdir_len); + wcsncpy(buffer_pos, wdir_pos, wdir_len); buffer_pos += wdir_len; } Index: ruby_2_0_0/version.h =================================================================== --- ruby_2_0_0/version.h (revision 40248) +++ ruby_2_0_0/version.h (revision 40249) @@ -1,10 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/version.h#L1 #define RUBY_VERSION "2.0.0" -#define RUBY_RELEASE_DATE "2013-04-08" -#define RUBY_PATCHLEVEL 111 +#define RUBY_RELEASE_DATE "2013-04-12" +#define RUBY_PATCHLEVEL 112 #define RUBY_RELEASE_YEAR 2013 #define RUBY_RELEASE_MONTH 4 -#define RUBY_RELEASE_DAY 8 +#define RUBY_RELEASE_DAY 12 #include "ruby/version.h" Index: ruby_2_0_0/test/ruby/test_file_exhaustive.rb =================================================================== --- ruby_2_0_0/test/ruby/test_file_exhaustive.rb (revision 40248) +++ ruby_2_0_0/test/ruby/test_file_exhaustive.rb (revision 40249) @@ -475,10 +475,12 @@ class TestFileExhaustive < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/test/ruby/test_file_exhaustive.rb#L475 ENV["HOME"] = home end + UnknownUserHome = "~foo_bar_baz_unknown_user_wahaha".freeze + def test_expand_path_home assert_kind_of(String, File.expand_path("~")) if ENV["HOME"] - assert_raise(ArgumentError) { File.expand_path("~foo_bar_baz_unknown_user_wahaha") } - assert_raise(ArgumentError) { File.expand_path("~foo_bar_baz_unknown_user_wahaha", "/") } + assert_raise(ArgumentError) { File.expand_path(UnknownUserHome) } + assert_raise(ArgumentError) { File.expand_path(UnknownUserHome, "/") } begin bug3630 = '[ruby-core:31537]' home = ENV["HOME"] @@ -502,6 +504,21 @@ class TestFileExhaustive < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/test/ruby/test_file_exhaustive.rb#L504 end end + def test_expand_path_home_dir_string + home = ENV["HOME"] + new_home = "#{DRIVE}/UserHome" + ENV["HOME"] = new_home + bug8034 = "[ruby-core:53168]" + + assert_equal File.join(new_home, "foo"), File.expand_path("foo", "~"), bug8034 + assert_equal File.join(new_home, "bar", "foo"), File.expand_path("foo", "~/bar"), bug8034 + + assert_raise(ArgumentError) { File.expand_path(".", UnknownUserHome) } + assert_nothing_raised(ArgumentError) { File.expand_path("#{DRIVE}/", UnknownUserHome) } + ensure + ENV["HOME"] = home + end + def test_expand_path_remove_trailing_alternative_data assert_equal File.join(@rootdir, "aaa"), File.expand_path("#{@rootdir}/aaa::$DATA") assert_equal File.join(@rootdir, "aa:a"), File.expand_path("#{@rootdir}/aa:a:$DATA") Property changes on: ruby_2_0_0 ___________________________________________________________________ Modified: svn:mergeinfo Merged /trunk:r39697,39701,39716,39740,39751 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/