summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--dir.c2
-rw-r--r--file.c28
-rw-r--r--include/ruby/ruby.h3
-rw-r--r--test/pathname/test_pathname.rb28
5 files changed, 68 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index ea9a19ca4..f12ab9a25 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+Sun Dec 9 14:08:47 2007 Tanaka Akira <akr@fsij.org>
+
+ * include/ruby/ruby.h (FilePathStringValue): defined. similar to
+ FilePathValue but no taint check.
+
+ * file.c (rb_get_path_no_checksafe): implementation of
+ FilePathStringValue.
+ (rb_file_s_basename): use FilePathStringValue.
+ (rb_file_s_dirname): ditto.
+ (rb_file_s_extname): ditto.
+ (rb_file_s_split): ditto.
+ (rb_file_join): ditto.
+
+ * dir.c (file_s_fnmatch): ditto.
+
Sun Dec 9 12:49:34 2007 Tanaka Akira <akr@fsij.org>
* re.c (append_utf8): check unicode range.
diff --git a/dir.c b/dir.c
index b26df63f7..c75a8e2e3 100644
--- a/dir.c
+++ b/dir.c
@@ -1849,7 +1849,7 @@ file_s_fnmatch(int argc, VALUE *argv, VALUE obj)
flags = 0;
StringValue(pattern);
- StringValue(path);
+ FilePathStringValue(path);
if (fnmatch(RSTRING_PTR(pattern), RSTRING_PTR(path), flags) == 0)
return Qtrue;
diff --git a/file.c b/file.c
index ac7ee25a5..c3cf72cb3 100644
--- a/file.c
+++ b/file.c
@@ -95,13 +95,13 @@ VALUE rb_cFile;
VALUE rb_mFileTest;
VALUE rb_cStat;
-VALUE
-rb_get_path(VALUE obj)
+static VALUE
+rb_get_path_check(VALUE obj, int check)
{
VALUE tmp;
static ID to_path;
- rb_check_safe_obj(obj);
+ if (check) rb_check_safe_obj(obj);
tmp = rb_check_string_type(obj);
if (!NIL_P(tmp)) goto exit;
@@ -116,12 +116,24 @@ rb_get_path(VALUE obj)
}
exit:
StringValueCStr(tmp);
- if (obj != tmp) {
+ if (check && obj != tmp) {
rb_check_safe_obj(tmp);
}
return rb_str_new4(tmp);
}
+VALUE
+rb_get_path_no_checksafe(VALUE obj)
+{
+ return rb_get_path_check(obj, 0);
+}
+
+VALUE
+rb_get_path(VALUE obj)
+{
+ return rb_get_path_check(obj, 1);
+}
+
static long
apply2files(void (*func)(const char *, void *), VALUE vargs, void *arg)
{
@@ -2809,7 +2821,7 @@ rb_file_s_basename(int argc, VALUE *argv)
if (rb_scan_args(argc, argv, "11", &fname, &fext) == 2) {
StringValue(fext);
}
- StringValue(fname);
+ FilePathStringValue(fname);
if (RSTRING_LEN(fname) == 0 || !*(name = RSTRING_PTR(fname)))
return fname;
name = skipprefix(name);
@@ -2874,6 +2886,7 @@ rb_file_s_dirname(VALUE klass, VALUE fname)
const char *name, *root, *p;
VALUE dirname;
+ FilePathStringValue(fname);
name = StringValueCStr(fname);
root = skiproot(name);
#ifdef DOSISH_UNC
@@ -2926,6 +2939,7 @@ rb_file_s_extname(VALUE klass, VALUE fname)
char *name, *p, *e;
VALUE extname;
+ FilePathStringValue(fname);
name = StringValueCStr(fname);
p = strrdirsep(name); /* get the last path component */
if (!p)
@@ -2972,7 +2986,7 @@ rb_file_s_path(VALUE klass, VALUE fname)
static VALUE
rb_file_s_split(VALUE klass, VALUE path)
{
- StringValue(path); /* get rid of converting twice */
+ FilePathStringValue(path); /* get rid of converting twice */
return rb_assoc_new(rb_file_s_dirname(Qnil, path), rb_file_s_basename(1,&path));
}
@@ -3027,7 +3041,7 @@ rb_file_join(VALUE ary, VALUE sep)
}
break;
default:
- FilePathValue(tmp);
+ FilePathStringValue(tmp);
}
name = StringValueCStr(result);
if (i > 0 && !NIL_P(sep)) {
diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h
index b0b5153b6..d86c990ad 100644
--- a/include/ruby/ruby.h
+++ b/include/ruby/ruby.h
@@ -326,6 +326,9 @@ void rb_check_safe_str(VALUE);
VALUE rb_get_path(VALUE);
#define FilePathValue(v) ((v) = rb_get_path(v))
+VALUE rb_get_path_no_checksafe(VALUE);
+#define FilePathStringValue(v) ((v) = rb_get_path_no_checksafe(v))
+
void rb_secure(int);
int rb_safe_level(void);
void rb_set_safe_level(int);
diff --git a/test/pathname/test_pathname.rb b/test/pathname/test_pathname.rb
index 9b0b9c01e..246b69f0e 100644
--- a/test/pathname/test_pathname.rb
+++ b/test/pathname/test_pathname.rb
@@ -475,4 +475,32 @@ class TestPathname < Test::Unit::TestCase
def test_kernel_pathname
assert_equal(Pathname.new("a"), Pathname("a"))
end
+
+ def test_file_basename
+ assert_equal("bar", File.basename(Pathname.new("foo/bar")))
+ end
+
+ def test_file_dirname
+ assert_equal("foo", File.dirname(Pathname.new("foo/bar")))
+ end
+
+ def test_file_split
+ assert_equal(["foo", "bar"], File.split(Pathname.new("foo/bar")))
+ end
+
+ def test_file_extname
+ assert_equal(".baz", File.extname(Pathname.new("bar.baz")))
+ end
+
+ def test_file_fnmatch
+ assert(File.fnmatch("*.*", Pathname.new("bar.baz")))
+ end
+
+ def test_file_join
+ assert_equal("foo/bar", File.join(Pathname.new("foo"), Pathname.new("bar")))
+ lambda {
+ $SAFE = 1
+ assert_equal("foo/bar", File.join(Pathname.new("foo"), Pathname.new("bar").taint))
+ }.call
+ end
end