Skip to content

Commit

Permalink
Add specs for tainted String
Browse files Browse the repository at this point in the history
  • Loading branch information
shirosaki committed Mar 15, 2012
1 parent db3eaed commit 5e32ca7
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
24 changes: 24 additions & 0 deletions ext/fenix/file.c
Expand Up @@ -408,10 +408,14 @@ fenix_file_expand_path(int argc, VALUE *argv)
wchar_t path_drive = L'\0', dir_drive = L'\0';
int ignore_dir = 0;
rb_encoding *path_encoding;
int tainted = 0;

// retrieve path and dir from argv
rb_scan_args(argc, argv, "11", &path, &dir);

/* tainted if path is tainted */
tainted = OBJ_TAINTED(path);

// get path encoding
if (NIL_P(dir)) {
path_encoding = rb_enc_get(path);
Expand All @@ -432,6 +436,9 @@ fenix_file_expand_path(int argc, VALUE *argv)
/* determine if we need the user's home directory */
if ((wpath_len == 1 && wpath_pos[0] == L'~') ||
(wpath_len >= 2 && wpath_pos[0] == L'~' && IS_DIR_SEPARATOR_P(wpath_pos[1]))) {
/* tainted if expanding '~' */
tainted = 1;

// wprintf(L"wpath requires expansion.\n");
whome = fenix_home_dir();
if (whome == NULL) {
Expand Down Expand Up @@ -473,6 +480,9 @@ fenix_file_expand_path(int argc, VALUE *argv)
wchar_t *pos = wuser;
char *user;

/* tainted if expanding '~' */
tainted = 1;

while (!IS_DIR_SEPARATOR_P(*pos) && *pos != '\0')
pos++;

Expand Down Expand Up @@ -574,6 +584,10 @@ fenix_file_expand_path(int argc, VALUE *argv)
}

if (wdir_len) {
/* tainted if dir is used and dir is tainted */
if (!tainted && OBJ_TAINTED(dir))
tainted = 1;

// wprintf(L"Copying wdir...\n");
wcsncpy(buffer_pos, wdir, wdir_len);
buffer_pos += wdir_len;
Expand Down Expand Up @@ -603,6 +617,12 @@ fenix_file_expand_path(int argc, VALUE *argv)
/* Ensure buffer is NULL terminated */
buffer_pos[0] = L'\0';


/* tainted if path is relative */
if (!tainted && PathIsRelativeW(buffer) && !(buffer_len >= 2 && IS_DIR_UNC_P(buffer))) {
tainted = 1;
}

// wprintf(L"buffer: '%s'\n", buffer);

// FIXME: Make this more robust
Expand Down Expand Up @@ -656,6 +676,10 @@ fenix_file_expand_path(int argc, VALUE *argv)

/* convert to VALUE and set the path encoding */
result = rb_enc_str_new(fullpath, size - 1, path_encoding);

/* makes the result object tainted if expanding tainted strings or returning modified path */
if (tainted)
OBJ_TAINT(result);
}

// TODO: better cleanup
Expand Down
20 changes: 20 additions & 0 deletions spec/fenix/file_spec.rb
Expand Up @@ -121,6 +121,26 @@
subject.expand_path('/foo').must_match %r"\A#{drive}/foo\z"i
end

it "returns tainted strings or not" do
subject.expand_path('foo').tainted?.must_equal true
subject.expand_path('foo'.taint).tainted?.must_equal true
subject.expand_path('/foo'.taint).tainted?.must_equal true
subject.expand_path('C:/foo'.taint).tainted?.must_equal true
subject.expand_path('/foo').tainted?.must_equal true
subject.expand_path('C:/foo').tainted?.must_equal false
subject.expand_path('//foo').tainted?.must_equal false
subject.expand_path('foo', 'bar').tainted?.must_equal true
subject.expand_path('foo', '/bar'.taint).tainted?.must_equal true
subject.expand_path('foo', 'C:/bar'.taint).tainted?.must_equal true
subject.expand_path('foo'.taint, '/bar').tainted?.must_equal true
subject.expand_path('foo'.taint, 'C:/bar').tainted?.must_equal true
subject.expand_path('foo', '/bar').tainted?.must_equal true
subject.expand_path('foo', 'C:/bar').tainted?.must_equal false
subject.expand_path('foo', '//bar').tainted?.must_equal false
subject.expand_path('~').tainted?.must_equal true
subject.expand_path('C:/foo/../bar').tainted?.must_equal false
end

describe "~/" do
let(:home) { "C:/UserHome" }
let(:home_drive) { nil }
Expand Down

0 comments on commit 5e32ca7

Please sign in to comment.