From ee90455a447aaafe1985ba365d0357ba8f524146 Mon Sep 17 00:00:00 2001 From: luislavena Date: Sun, 10 Mar 2013 14:39:09 +0000 Subject: [PATCH] Expand home directory when used in dir_string * 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39697 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 6 +++++ test/ruby/test_file_exhaustive.rb | 12 ++++++++++ win32/file.c | 38 +++++++++++++++++++++++++++---- 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index da43fbfdef..47d3c4c664 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Sun Mar 10 23:38:15 2013 Luis Lavena + + * 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. + Sun Mar 10 23:27:54 2013 Nobuyoshi Nakada * lib/rubygems/ext/ext_conf_builder.rb (Gem::Ext::ExtConfBuilder.build): diff --git a/test/ruby/test_file_exhaustive.rb b/test/ruby/test_file_exhaustive.rb index 360a1c7cce..25cb92ea36 100644 --- a/test/ruby/test_file_exhaustive.rb +++ b/test/ruby/test_file_exhaustive.rb @@ -502,6 +502,18 @@ class TestFileExhaustive < Test::Unit::TestCase 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", "~") + assert_equal File.join(new_home, "bar", "foo"), File.expand_path("foo", "~/bar") + ensure + ENV["HOME"] = home + end if DRIVE + 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") diff --git a/win32/file.c b/win32/file.c index dfe122480f..10fd4cbf42 100644 --- a/win32/file.c +++ b/win32/file.c @@ -323,7 +323,8 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na 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; @@ -442,9 +443,38 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na } /* 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 (wdir_len >= 2 && wdir[1] == L':') { + 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; + + 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; @@ -515,7 +545,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na if (!tainted && OBJ_TAINTED(dir)) tainted = 1; - wcsncpy(buffer_pos, wdir, wdir_len); + wcsncpy(buffer_pos, wdir_pos, wdir_len); buffer_pos += wdir_len; }