Skip to content

Instantly share code, notes, and snippets.

@shirosaki
Created March 20, 2012 04:41
Show Gist options
  • Save shirosaki/2131421 to your computer and use it in GitHub Desktop.
Save shirosaki/2131421 to your computer and use it in GitHub Desktop.
Add processing of rb_get_path_check
user system total real
Ruby '' 0.032000 0.000000 0.032000 ( 0.031200)
Fenix '' 0.031000 0.000000 0.031000 ( 0.031200)
Plain '' 0.031000 0.000000 0.031000 ( 0.031200)
Ruby '.' 0.031000 0.000000 0.031000 ( 0.031200)
Fenix '.' 0.031000 0.000000 0.031000 ( 0.031200)
Plain '.' 0.032000 0.000000 0.032000 ( 0.031200)
Ruby 'foo', 'bar' 0.031000 0.000000 0.031000 ( 0.031200)
Fenix 'foo', 'bar' 0.047000 0.000000 0.047000 ( 0.046800)
Plain 'foo', 'bar' 0.031000 0.000000 0.031000 ( 0.031200)
Ruby '', 'C:/' 0.031000 0.000000 0.031000 ( 0.031200)
Fenix '', 'C:/' 0.031000 0.000000 0.031000 ( 0.031200)
Plain '', 'C:/' 0.031000 0.000000 0.031000 ( 0.031200)
Ruby 'foo', 'C:/' 0.032000 0.000000 0.032000 ( 0.031200)
Fenix 'foo', 'C:/' 0.015000 0.000000 0.015000 ( 0.015600)
Plain 'foo', 'C:/' 0.015000 0.000000 0.015000 ( 0.015600)
Ruby '~' 0.047000 0.000000 0.047000 ( 0.046800)
Fenix '~' 0.031000 0.000000 0.031000 ( 0.031200)
Plain '~' 0.032000 0.000000 0.032000 ( 0.031201)
Ruby '~/foo' 0.031000 0.000000 0.031000 ( 0.031200)
Fenix '~/foo' 0.031000 0.000000 0.031000 ( 0.031200)
Plain '~/foo' 0.031000 0.000000 0.031000 ( 0.031200)
Ruby 'foo/' 0.031000 0.000000 0.031000 ( 0.031200)
Fenix 'foo/' 0.032000 0.000000 0.032000 ( 0.031200)
Plain 'foo/' 0.031000 0.000000 0.031000 ( 0.031200)
Ruby '~', 'C:/Foo' 0.047000 0.000000 0.047000 ( 0.046800)
Fenix '~', 'C:/Foo' 0.031000 0.000000 0.031000 ( 0.031200)
Plain '~', 'C:/Foo' 0.031000 0.000000 0.031000 ( 0.031200)
Ruby long_path 0.109000 0.000000 0.109000 ( 0.109200)
Fenix long_path 0.109000 0.000000 0.109000 ( 0.109200)
Plain long_path 0.110000 0.000000 0.110000 ( 0.109201)
Ruby long_path, 'rel' 0.109000 0.000000 0.109000 ( 0.109200)
Fenix long_path, 'rel' 0.109000 0.000000 0.109000 ( 0.109200)
Plain long_path, 'rel' 0.109000 0.000000 0.109000 ( 0.109200)
Ruby long_path, 'C:/Foo' 0.109000 0.000000 0.109000 ( 0.109200)
Fenix long_path, 'C:/Foo' 0.109000 0.000000 0.109000 ( 0.109201)
Plain long_path, 'C:/Foo' 0.094000 0.000000 0.094000 ( 0.093600)
Ruby full_long_path 0.109000 0.000000 0.109000 ( 0.109200)
Fenix full_long_path 0.094000 0.000000 0.094000 ( 0.093600)
Plain full_long_path 0.093000 0.000000 0.093000 ( 0.093600)
Ruby to_path 0.031000 0.000000 0.031000 ( 0.031200)
Fenix to_path 0.031000 0.000000 0.031000 ( 0.031200)
Plain to_path 0.031000 0.000000 0.031000 ( 0.031200)
Ruby to_path, 'rel' 0.047000 0.000000 0.047000 ( 0.046801)
Fenix to_path, 'rel' 0.047000 0.000000 0.047000 ( 0.046800)
Plain to_path, 'rel' 0.031000 0.000000 0.031000 ( 0.031200)
Ruby to_path, 'C:/Foo' 0.031000 0.000000 0.031000 ( 0.031200)
Fenix to_path, 'C:/Foo' 0.031000 0.000000 0.031000 ( 0.031200)
Plain to_path, 'C:/Foo' 0.047000 0.000000 0.047000 ( 0.046800)
Ruby full_to_path 0.016000 0.000000 0.016000 ( 0.015600)
Fenix full_to_path 0.031000 0.000000 0.031000 ( 0.031200)
Plain full_to_path 0.031000 0.000000 0.031000 ( 0.031200)
diff --git a/ext/fenix/file.c b/ext/fenix/file.c
index fc17e76..db1f8e0 100644
--- a/ext/fenix/file.c
+++ b/ext/fenix/file.c
@@ -78,18 +78,57 @@ fenix_home_dir()
return NULL;
}
+#define insecure_obj_p(obj, level) ((level) >= 4 || ((level) > 0 && OBJ_TAINTED(obj)))
+
+static VALUE
+file_path_convert(VALUE name)
+{
+#ifndef _WIN32 /* non Windows == Unix */
+ rb_encoding *fname_encoding = rb_enc_from_index(ENCODING_GET(name));
+ rb_encoding *fs_encoding;
+ if (rb_default_internal_encoding() != NULL
+ && rb_usascii_encoding() != fname_encoding
+ && rb_ascii8bit_encoding() != fname_encoding
+ && (fs_encoding = rb_filesystem_encoding()) != fname_encoding
+ && !rb_enc_str_asciionly_p(name)) {
+ /* Don't call rb_filesystem_encoding() before US-ASCII and ASCII-8BIT */
+ /* fs_encoding should be ascii compatible */
+ name = rb_str_conv_enc(name, fname_encoding, fs_encoding);
+ }
+#endif
+ return name;
+}
+
static VALUE
fenix_coerce_to_path(VALUE obj)
{
VALUE tmp;
ID to_path;
+ rb_encoding *enc;
+ int level = rb_safe_level();
+
+ if (insecure_obj_p(obj, level)) {
+ rb_insecure_operation();
+ }
CONST_ID(to_path, "to_path");
tmp = rb_check_funcall(obj, to_path, 0, 0);
if (tmp == Qundef)
tmp = obj;
- return StringValue(tmp);
+ StringValue(tmp);
+
+ tmp = file_path_convert(tmp);
+ if (obj != tmp && insecure_obj_p(tmp, level)) {
+ rb_insecure_operation();
+ }
+ enc = rb_enc_get(tmp);
+ if (!rb_enc_asciicompat(enc)) {
+ tmp = rb_str_inspect(tmp);
+ rb_raise(rb_eEncCompatError, "path name must be ASCII-compatible (%s): %s",
+ rb_enc_name(enc), RSTRING_PTR(tmp));
+ }
+ return rb_str_new4(tmp);
}
// TODO: can we fail allocating memory?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment