diff options
Diffstat (limited to 'ext/cgi/escape')
| -rw-r--r-- | ext/cgi/escape/depend | 5 | ||||
| -rw-r--r-- | ext/cgi/escape/escape.c | 118 | ||||
| -rw-r--r-- | ext/cgi/escape/extconf.rb | 6 |
3 files changed, 100 insertions, 29 deletions
diff --git a/ext/cgi/escape/depend b/ext/cgi/escape/depend index e3904d0695..05b59bfdea 100644 --- a/ext/cgi/escape/depend +++ b/ext/cgi/escape/depend @@ -53,6 +53,7 @@ escape.o: $(hdrdir)/ruby/internal/attr/noexcept.h escape.o: $(hdrdir)/ruby/internal/attr/noinline.h escape.o: $(hdrdir)/ruby/internal/attr/nonnull.h escape.o: $(hdrdir)/ruby/internal/attr/noreturn.h +escape.o: $(hdrdir)/ruby/internal/attr/packed_struct.h escape.o: $(hdrdir)/ruby/internal/attr/pure.h escape.o: $(hdrdir)/ruby/internal/attr/restrict.h escape.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -121,7 +122,6 @@ escape.o: $(hdrdir)/ruby/internal/intern/enumerator.h escape.o: $(hdrdir)/ruby/internal/intern/error.h escape.o: $(hdrdir)/ruby/internal/intern/eval.h escape.o: $(hdrdir)/ruby/internal/intern/file.h -escape.o: $(hdrdir)/ruby/internal/intern/gc.h escape.o: $(hdrdir)/ruby/internal/intern/hash.h escape.o: $(hdrdir)/ruby/internal/intern/io.h escape.o: $(hdrdir)/ruby/internal/intern/load.h @@ -138,6 +138,7 @@ escape.o: $(hdrdir)/ruby/internal/intern/re.h escape.o: $(hdrdir)/ruby/internal/intern/ruby.h escape.o: $(hdrdir)/ruby/internal/intern/select.h escape.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +escape.o: $(hdrdir)/ruby/internal/intern/set.h escape.o: $(hdrdir)/ruby/internal/intern/signal.h escape.o: $(hdrdir)/ruby/internal/intern/sprintf.h escape.o: $(hdrdir)/ruby/internal/intern/string.h @@ -152,12 +153,12 @@ escape.o: $(hdrdir)/ruby/internal/memory.h escape.o: $(hdrdir)/ruby/internal/method.h escape.o: $(hdrdir)/ruby/internal/module.h escape.o: $(hdrdir)/ruby/internal/newobj.h -escape.o: $(hdrdir)/ruby/internal/rgengc.h escape.o: $(hdrdir)/ruby/internal/scan_args.h escape.o: $(hdrdir)/ruby/internal/special_consts.h escape.o: $(hdrdir)/ruby/internal/static_assert.h escape.o: $(hdrdir)/ruby/internal/stdalign.h escape.o: $(hdrdir)/ruby/internal/stdbool.h +escape.o: $(hdrdir)/ruby/internal/stdckdint.h escape.o: $(hdrdir)/ruby/internal/symbol.h escape.o: $(hdrdir)/ruby/internal/value.h escape.o: $(hdrdir)/ruby/internal/value_type.h diff --git a/ext/cgi/escape/escape.c b/ext/cgi/escape/escape.c index 068647747d..4773186603 100644 --- a/ext/cgi/escape/escape.c +++ b/ext/cgi/escape/escape.c @@ -8,7 +8,7 @@ RUBY_EXTERN const signed char ruby_digit36_to_number_table[]; #define upper_hexdigits (ruby_hexdigits+16) #define char_to_number(c) ruby_digit36_to_number_table[(unsigned char)(c)] -static VALUE rb_cCGI, rb_mUtil, rb_mEscape; +static VALUE rb_cCGI, rb_mEscape, rb_mEscapeExt; static ID id_accept_charset; #define HTML_ESCAPE_MAX_LEN 6 @@ -45,6 +45,7 @@ escaped_length(VALUE str) static VALUE optimized_escape_html(VALUE str) { + VALUE escaped; VALUE vbuf; char *buf = ALLOCV_N(char, vbuf, escaped_length(str)); const char *cstr = RSTRING_PTR(str); @@ -63,7 +64,6 @@ optimized_escape_html(VALUE str) } } - VALUE escaped; if (RSTRING_LEN(str) < (dest - buf)) { escaped = rb_str_new(buf, dest - buf); preserve_original_state(str, escaped); @@ -83,7 +83,7 @@ optimized_unescape_html(VALUE str) unsigned long charlimit = (strcasecmp(rb_enc_name(enc), "UTF-8") == 0 ? UNICODE_MAX : strcasecmp(rb_enc_name(enc), "ISO-8859-1") == 0 ? 256 : 128); - long i, len, beg = 0; + long i, j, len, beg = 0; size_t clen, plen; int overflow; const char *cstr; @@ -100,6 +100,7 @@ optimized_unescape_html(VALUE str) plen = i - beg; if (++i >= len) break; c = (unsigned char)cstr[i]; + j = i; #define MATCH(s) (len - i >= (int)rb_strlen_lit(s) && \ memcmp(&cstr[i], s, rb_strlen_lit(s)) == 0 && \ (i += rb_strlen_lit(s) - 1, 1)) @@ -112,28 +113,40 @@ optimized_unescape_html(VALUE str) else if (MATCH("mp;")) { c = '&'; } - else continue; + else { + i = j; + continue; + } break; case 'q': ++i; if (MATCH("uot;")) { c = '"'; } - else continue; + else { + i = j; + continue; + } break; case 'g': ++i; if (MATCH("t;")) { c = '>'; } - else continue; + else { + i = j; + continue; + } break; case 'l': ++i; if (MATCH("t;")) { c = '<'; } - else continue; + else { + i = j; + continue; + } break; case '#': if (len - ++i >= 2 && ISDIGIT(cstr[i])) { @@ -142,9 +155,15 @@ optimized_unescape_html(VALUE str) else if ((cstr[i] == 'x' || cstr[i] == 'X') && len - ++i >= 2 && ISXDIGIT(cstr[i])) { cc = ruby_scan_digits(&cstr[i], len-i, 16, &clen, &overflow); } - else continue; + else { + i = j; + continue; + } i += clen; - if (overflow || cc >= charlimit || cstr[i] != ';') continue; + if (overflow || cc >= charlimit || cstr[i] != ';') { + i = j; + continue; + } if (!dest) { dest = rb_str_buf_new(len); } @@ -200,7 +219,7 @@ url_unreserved_char(unsigned char c) } static VALUE -optimized_escape(VALUE str) +optimized_escape(VALUE str, int plus_escape) { long i, len, beg = 0; VALUE dest = 0; @@ -220,7 +239,7 @@ optimized_escape(VALUE str) rb_str_cat(dest, cstr + beg, i - beg); beg = i + 1; - if (c == ' ') { + if (plus_escape && c == ' ') { rb_str_cat_cstr(dest, "+"); } else { @@ -242,7 +261,7 @@ optimized_escape(VALUE str) } static VALUE -optimized_unescape(VALUE str, VALUE encoding) +optimized_unescape(VALUE str, VALUE encoding, int unescape_plus) { long i, len, beg = 0; VALUE dest = 0; @@ -265,7 +284,7 @@ optimized_unescape(VALUE str, VALUE encoding) | char_to_number(cstr[i+2])); clen = 2; } - else if (c == '+') { + else if (unescape_plus && c == '+') { buf[0] = ' '; } else { @@ -348,7 +367,7 @@ cgiesc_unescape_html(VALUE self, VALUE str) * call-seq: * CGI.escape(string) -> string * - * Returns URL-escaped string. + * Returns URL-escaped string (+application/x-www-form-urlencoded+). * */ static VALUE @@ -357,7 +376,7 @@ cgiesc_escape(VALUE self, VALUE str) StringValue(str); if (rb_enc_str_asciicompat_p(str)) { - return optimized_escape(str); + return optimized_escape(str, 1); } else { return rb_call_super(1, &str); @@ -376,7 +395,7 @@ accept_charset(int argc, VALUE *argv, VALUE self) * call-seq: * CGI.unescape(string, encoding=@@accept_charset) -> string * - * Returns URL-unescaped string. + * Returns URL-unescaped string (+application/x-www-form-urlencoded+). * */ static VALUE @@ -388,7 +407,50 @@ cgiesc_unescape(int argc, VALUE *argv, VALUE self) if (rb_enc_str_asciicompat_p(str)) { VALUE enc = accept_charset(argc-1, argv+1, self); - return optimized_unescape(str, enc); + return optimized_unescape(str, enc, 1); + } + else { + return rb_call_super(argc, argv); + } +} + +/* + * call-seq: + * CGI.escapeURIComponent(string) -> string + * + * Returns URL-escaped string following RFC 3986. + * + */ +static VALUE +cgiesc_escape_uri_component(VALUE self, VALUE str) +{ + StringValue(str); + + if (rb_enc_str_asciicompat_p(str)) { + return optimized_escape(str, 0); + } + else { + return rb_call_super(1, &str); + } +} + +/* + * call-seq: + * CGI.unescapeURIComponent(string, encoding=@@accept_charset) -> string + * + * Returns URL-unescaped string following RFC 3986. + * + */ +static VALUE +cgiesc_unescape_uri_component(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, 0); } else { return rb_call_super(argc, argv); @@ -409,13 +471,17 @@ Init_escape(void) void InitVM_escape(void) { - rb_cCGI = rb_define_class("CGI", rb_cObject); - rb_mEscape = rb_define_module_under(rb_cCGI, "Escape"); - rb_mUtil = rb_define_module_under(rb_cCGI, "Util"); - 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_method(rb_mEscape, "unescape", cgiesc_unescape, -1); - rb_prepend_module(rb_mUtil, rb_mEscape); - rb_extend_object(rb_cCGI, rb_mEscape); + rb_cCGI = rb_define_class("CGI", rb_cObject); + rb_mEscapeExt = rb_define_module_under(rb_cCGI, "EscapeExt"); + rb_mEscape = rb_define_module_under(rb_cCGI, "Escape"); + rb_define_method(rb_mEscapeExt, "escapeHTML", cgiesc_escape_html, 1); + rb_define_method(rb_mEscapeExt, "unescapeHTML", cgiesc_unescape_html, 1); + rb_define_method(rb_mEscapeExt, "escapeURIComponent", cgiesc_escape_uri_component, 1); + rb_define_alias(rb_mEscapeExt, "escape_uri_component", "escapeURIComponent"); + rb_define_method(rb_mEscapeExt, "unescapeURIComponent", cgiesc_unescape_uri_component, -1); + rb_define_alias(rb_mEscapeExt, "unescape_uri_component", "unescapeURIComponent"); + rb_define_method(rb_mEscapeExt, "escape", cgiesc_escape, 1); + rb_define_method(rb_mEscapeExt, "unescape", cgiesc_unescape, -1); + rb_prepend_module(rb_mEscape, rb_mEscapeExt); + rb_extend_object(rb_cCGI, rb_mEscapeExt); } diff --git a/ext/cgi/escape/extconf.rb b/ext/cgi/escape/extconf.rb index 16e8ff224d..73acd89ca8 100644 --- a/ext/cgi/escape/extconf.rb +++ b/ext/cgi/escape/extconf.rb @@ -1,3 +1,7 @@ require 'mkmf' -create_makefile 'cgi/escape' +if RUBY_ENGINE == 'truffleruby' + File.write("Makefile", dummy_makefile($srcdir).join("")) +else + create_makefile 'cgi/escape' +end |
