Skip to content

Instantly share code, notes, and snippets.

@luislavena
Last active December 14, 2015 21:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save luislavena/5148562 to your computer and use it in GitHub Desktop.
Save luislavena/5148562 to your computer and use it in GitHub Desktop.
diff --git a/test/ruby/test_file_exhaustive.rb b/test/ruby/test_file_exhaustive.rb
index d3a44d1..a388fd4 100644
--- a/test/ruby/test_file_exhaustive.rb
+++ b/test/ruby/test_file_exhaustive.rb
@@ -669,6 +669,12 @@ class TestFileExhaustive < Test::Unit::TestCase
assert_raise(ArgumentError, bug) { File.expand_path("~anything") }
end if DRIVE
+ def test_expand_path_raises_argument_error_for_username_in_dir_string
+ bug8034 = "[ruby-core:53168]"
+
+ assert_raise(ArgumentError, bug8034) { File.expand_path("something", "~whoever") }
+ end if DRIVE
+
def test_expand_path_raises_a_type_error_if_not_passed_a_string_type
assert_raise(TypeError) { File.expand_path(1) }
assert_raise(TypeError) { File.expand_path(nil) }
diff --git a/win32/file.c b/win32/file.c
index 10fd4cb..aec9c6c 100644
--- a/win32/file.c
+++ b/win32/file.c
@@ -317,6 +317,39 @@ 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 +438,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);
- xfree(wpath);
- if (user)
- xfree(user);
+ if (wpath)
+ xfree(wpath);
rb_raise(rb_eArgError, "can't find user %s", StringValuePtr(result));
}
@@ -496,6 +507,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 */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment