Refactor rb_file_expand_path_internal for dir_string corner cases

* 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/trunk@39751 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
luislavena 2013-03-14 03:56:09 +00:00
Родитель ca4397ad2c
Коммит 2caf0bc820
2 изменённых файлов: 52 добавлений и 25 удалений

Просмотреть файл

@ -1,3 +1,11 @@
Thu Mar 14 12:53:15 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]
Thu Mar 14 11:53:01 2013 Narihiro Nakamura <authornari@gmail.com>
* NEWS: describe RUBY_HEAP_SLOTS_GROWTH_FACTOR.

Просмотреть файл

@ -317,6 +317,37 @@ 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)
{
@ -405,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;
result = get_user_from_path(&wpath_pos, 1, cp, path_cp, path_encoding);
/* 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);
}
xfree(wpath);
if (user)
xfree(user);
if (wpath)
xfree(wpath);
rb_raise(rb_eArgError, "can't find user %s", StringValuePtr(result));
}
@ -496,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 */