summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--ext/cgi/escape/escape.c25
-rw-r--r--lib/cgi/util.rb4
-rw-r--r--test/cgi/test_cgi_util.rb17
4 files changed, 47 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 4dd2294c08..e228cfefca 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Wed Apr 20 17:33:31 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * ext/cgi/escape/escape.c (cgiesc_unescape): define unescape
+ method instead of _unescape, and should pass the optional
+ argument to the super method.
+
+ * lib/cgi/util.rb (CGI::Util#_unescape): remove intermediate
+ method.
+
Wed Apr 20 15:52:28 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
* error.c (syntax_error_initialize): move the default message,
diff --git a/ext/cgi/escape/escape.c b/ext/cgi/escape/escape.c
index 4f6a82a144..75278a5399 100644
--- a/ext/cgi/escape/escape.c
+++ b/ext/cgi/escape/escape.c
@@ -369,17 +369,34 @@ cgiesc_escape(VALUE self, VALUE str)
}
}
-/* :nodoc: */
static VALUE
-cgiesc_unescape(VALUE self, VALUE str, VALUE enc)
+accept_charset(int argc, VALUE *argv, VALUE self)
{
+ if (argc > 0)
+ return argv[0];
+ return rb_cvar_get(CLASS_OF(self), rb_intern("@@accept_charset"));
+}
+
+/*
+ * call-seq:
+ * CGI.unescape(string, encoding=@@accept_charset) -> string
+ *
+ * Returns URL-unescaped string.
+ *
+ */
+static VALUE
+cgiesc_unescape(int argc, VALUE *argv, VALUE self)
+{
+ VALUE str = (rb_check_arity(argc, 1, 2), argv[0]);
+
StringValue(str);
if (rb_enc_str_asciicompat_p(str)) {
+ VALUE enc = accept_charset(argc-1, argv+1, self);
return optimized_unescape(str, enc);
}
else {
- return rb_call_super(1, &str);
+ return rb_call_super(argc, argv);
}
}
@@ -392,7 +409,7 @@ Init_escape(void)
rb_define_method(rb_mEscape, "escapeHTML", cgiesc_escape_html, 1);
rb_define_method(rb_mEscape, "unescapeHTML", cgiesc_unescape_html, 1);
rb_define_method(rb_mEscape, "escape", cgiesc_escape, 1);
- rb_define_private_method(rb_mEscape, "_unescape", cgiesc_unescape, 2);
+ rb_define_method(rb_mEscape, "unescape", cgiesc_unescape, -1);
rb_prepend_module(rb_mUtil, rb_mEscape);
rb_extend_object(rb_cCGI, rb_mEscape);
}
diff --git a/lib/cgi/util.rb b/lib/cgi/util.rb
index 7968c9326e..d2657ab981 100644
--- a/lib/cgi/util.rb
+++ b/lib/cgi/util.rb
@@ -16,10 +16,6 @@ module CGI::Util
# string = CGI::unescape("%27Stop%21%27+said+Fred")
# # => "'Stop!' said Fred"
def unescape(string,encoding=@@accept_charset)
- _unescape(string,encoding)
- end
-
- private def _unescape(string, encoding)
str=string.tr('+', ' ').b.gsub(/((?:%[0-9a-fA-F]{2})+)/) do |m|
[m.delete('%')].pack('H*')
end.force_encoding(encoding)
diff --git a/test/cgi/test_cgi_util.rb b/test/cgi/test_cgi_util.rb
index 62679b9c82..4e4f7a45e7 100644
--- a/test/cgi/test_cgi_util.rb
+++ b/test/cgi/test_cgi_util.rb
@@ -118,6 +118,23 @@ class CGIUtilTest < Test::Unit::TestCase
end
end
+ Encoding.list.each do |enc|
+ next unless enc.ascii_compatible?
+ begin
+ escaped = "%25+%2B"
+ unescaped = "% +".encode(enc)
+ rescue Encoding::ConverterNotFoundError
+ next
+ else
+ define_method("test_cgi_escape:#{enc.name}") do
+ assert_equal(escaped, CGI::escape(unescaped))
+ end
+ define_method("test_cgi_unescape:#{enc.name}") do
+ assert_equal(unescaped, CGI::unescape(escaped, enc))
+ end
+ end
+ end
+
def test_cgi_unescapeHTML_uppercasecharacter
assert_equal("\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86", CGI::unescapeHTML("&#x3042;&#x3044;&#X3046;"))
end