mirror of
https://github.com/ruby/ruby.git
synced 2025-09-17 01:23:57 +02:00
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] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_0_0@40249 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
8e4d69ade4
commit
a7256d7a00
4 changed files with 114 additions and 34 deletions
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
|||
Fri Apr 12 01:28:46 2013 Luis Lavena <luislavena@gmail.com>
|
||||
|
||||
* 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@gmail.com>
|
||||
|
||||
* 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@gmail.com>
|
||||
|
||||
* gc.c: Fix unlimited memory growth with large values of
|
||||
|
|
|
@ -475,10 +475,12 @@ class TestFileExhaustive < Test::Unit::TestCase
|
|||
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::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", "~"), 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")
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#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"
|
||||
|
||||
|
|
105
win32/file.c
105
win32/file.c
|
@ -317,13 +317,45 @@ replace_to_long_name(wchar_t **wfullpath, size_t size, int heap)
|
|||
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, VALUE dname, int abs_mode, int long_na
|
|||
}
|
||||
}
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
result = get_user_from_path(&wpath_pos, 1, cp, path_cp, path_encoding);
|
||||
|
||||
if (wpath)
|
||||
xfree(wpath);
|
||||
if (user)
|
||||
xfree(user);
|
||||
|
||||
rb_raise(rb_eArgError, "can't find user %s", StringValuePtr(result));
|
||||
}
|
||||
|
@ -442,9 +452,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;
|
||||
|
@ -466,6 +505,16 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
|
|||
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, 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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue