* 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.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@14155 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
akr 2007-12-09 05:12:31 +00:00
parent 5a1c2b2677
commit 3a8f7f1d7f
5 changed files with 68 additions and 8 deletions

View File

@ -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> Sun Dec 9 12:49:34 2007 Tanaka Akira <akr@fsij.org>
* re.c (append_utf8): check unicode range. * re.c (append_utf8): check unicode range.

2
dir.c
View File

@ -1849,7 +1849,7 @@ file_s_fnmatch(int argc, VALUE *argv, VALUE obj)
flags = 0; flags = 0;
StringValue(pattern); StringValue(pattern);
StringValue(path); FilePathStringValue(path);
if (fnmatch(RSTRING_PTR(pattern), RSTRING_PTR(path), flags) == 0) if (fnmatch(RSTRING_PTR(pattern), RSTRING_PTR(path), flags) == 0)
return Qtrue; return Qtrue;

28
file.c
View File

@ -95,13 +95,13 @@ VALUE rb_cFile;
VALUE rb_mFileTest; VALUE rb_mFileTest;
VALUE rb_cStat; VALUE rb_cStat;
VALUE static VALUE
rb_get_path(VALUE obj) rb_get_path_check(VALUE obj, int check)
{ {
VALUE tmp; VALUE tmp;
static ID to_path; static ID to_path;
rb_check_safe_obj(obj); if (check) rb_check_safe_obj(obj);
tmp = rb_check_string_type(obj); tmp = rb_check_string_type(obj);
if (!NIL_P(tmp)) goto exit; if (!NIL_P(tmp)) goto exit;
@ -116,12 +116,24 @@ rb_get_path(VALUE obj)
} }
exit: exit:
StringValueCStr(tmp); StringValueCStr(tmp);
if (obj != tmp) { if (check && obj != tmp) {
rb_check_safe_obj(tmp); rb_check_safe_obj(tmp);
} }
return rb_str_new4(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 static long
apply2files(void (*func)(const char *, void *), VALUE vargs, void *arg) 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) { if (rb_scan_args(argc, argv, "11", &fname, &fext) == 2) {
StringValue(fext); StringValue(fext);
} }
StringValue(fname); FilePathStringValue(fname);
if (RSTRING_LEN(fname) == 0 || !*(name = RSTRING_PTR(fname))) if (RSTRING_LEN(fname) == 0 || !*(name = RSTRING_PTR(fname)))
return fname; return fname;
name = skipprefix(name); name = skipprefix(name);
@ -2874,6 +2886,7 @@ rb_file_s_dirname(VALUE klass, VALUE fname)
const char *name, *root, *p; const char *name, *root, *p;
VALUE dirname; VALUE dirname;
FilePathStringValue(fname);
name = StringValueCStr(fname); name = StringValueCStr(fname);
root = skiproot(name); root = skiproot(name);
#ifdef DOSISH_UNC #ifdef DOSISH_UNC
@ -2926,6 +2939,7 @@ rb_file_s_extname(VALUE klass, VALUE fname)
char *name, *p, *e; char *name, *p, *e;
VALUE extname; VALUE extname;
FilePathStringValue(fname);
name = StringValueCStr(fname); name = StringValueCStr(fname);
p = strrdirsep(name); /* get the last path component */ p = strrdirsep(name); /* get the last path component */
if (!p) if (!p)
@ -2972,7 +2986,7 @@ rb_file_s_path(VALUE klass, VALUE fname)
static VALUE static VALUE
rb_file_s_split(VALUE klass, VALUE path) 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)); 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; break;
default: default:
FilePathValue(tmp); FilePathStringValue(tmp);
} }
name = StringValueCStr(result); name = StringValueCStr(result);
if (i > 0 && !NIL_P(sep)) { if (i > 0 && !NIL_P(sep)) {

View File

@ -326,6 +326,9 @@ void rb_check_safe_str(VALUE);
VALUE rb_get_path(VALUE); VALUE rb_get_path(VALUE);
#define FilePathValue(v) ((v) = rb_get_path(v)) #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); void rb_secure(int);
int rb_safe_level(void); int rb_safe_level(void);
void rb_set_safe_level(int); void rb_set_safe_level(int);

View File

@ -475,4 +475,32 @@ class TestPathname < Test::Unit::TestCase
def test_kernel_pathname def test_kernel_pathname
assert_equal(Pathname.new("a"), Pathname("a")) assert_equal(Pathname.new("a"), Pathname("a"))
end 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 end