Skip to content

Commit

Permalink
Implement escapeURIComponent for JRuby
Browse files Browse the repository at this point in the history
  • Loading branch information
byroot committed Nov 7, 2023
1 parent a60754b commit 04498c7
Showing 1 changed file with 44 additions and 5 deletions.
49 changes: 44 additions & 5 deletions ext/java/org/jruby/ext/cgi/escape/CGIEscape.java
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ static boolean url_unreserved_char(int c) {

static final byte[] upper_hexdigits = "0123456789ABCDEF".getBytes(RubyEncoding.UTF8);

static IRubyObject optimized_escape(Ruby runtime, RubyString str) {
static IRubyObject optimized_escape(Ruby runtime, RubyString str, boolean escapePlus) {
int i, len, beg = 0;
RubyString dest = null;
byte[] cstrBytes;
Expand Down Expand Up @@ -305,7 +305,7 @@ static IRubyObject optimized_escape(Ruby runtime, RubyString str) {
}

static IRubyObject
optimized_unescape(ThreadContext context, RubyString str, IRubyObject encoding) {
optimized_unescape(ThreadContext context, RubyString str, IRubyObject encoding, boolean unescapePlus) {
int i, len, beg = 0;
RubyString dest = null;
byte[] cstrBytes;
Expand All @@ -331,7 +331,7 @@ static IRubyObject optimized_escape(Ruby runtime, RubyString str) {
buf = ((char_to_number(cstrBytes[cstr + i + 1]) << 4)
| char_to_number(cstrBytes[cstr + i + 2]));
clen = 2;
} else if (c == '+') {
} else if (unescapePlus && c == '+') {
buf = ' ';
} else {
continue;
Expand Down Expand Up @@ -416,7 +416,25 @@ public static IRubyObject cgiesc_escape(ThreadContext context, IRubyObject self,
RubyString str = _str.convertToString();

if (str.getEncoding().isAsciiCompatible()) {
return optimized_escape(context.runtime, str);
return optimized_escape(context.runtime, str, true);
} else {
return Helpers.invokeSuper(context, self, _str, Block.NULL_BLOCK);
}
}

/*
* call-seq:
* CGI.escapeURIComponent(string) -> string
*
* Returns URL-escaped string following RFC 3986.
*
*/
@JRubyMethod(name = "escapeURIComponent", alias = { "escape_uri_component" }, module = true, frame = true)
public static IRubyObject cgiesc_escape_uri_component(ThreadContext context, IRubyObject self, IRubyObject _str) {
RubyString str = _str.convertToString();

if (str.getEncoding().isAsciiCompatible()) {
return optimized_escape(context.runtime, str, false);
} else {
return Helpers.invokeSuper(context, self, _str, Block.NULL_BLOCK);
}
Expand All @@ -443,7 +461,28 @@ public static IRubyObject cgiesc_unescape(ThreadContext context, IRubyObject sel

if (str.getEncoding().isAsciiCompatible()) {
IRubyObject enc = accept_charset(argv, argv.length - 1, 1, self);
return optimized_unescape(context, str, enc);
return optimized_unescape(context, str, enc, true);
} else {
return Helpers.invokeSuper(context, self, argv, Block.NULL_BLOCK);
}
}

/*
* call-seq:
* CGI.unescapeURIComponent(string, encoding=@@accept_charset) -> string
*
* Returns URL-unescaped string following RFC 3986.
*
*/
@JRubyMethod(name = "unescapeURIComponent", alias = { "unescape_uri_component" }, required = 1, optional = 1, module = true, frame = true)
public static IRubyObject cgiesc_unescape_uri_component(ThreadContext context, IRubyObject self, IRubyObject[] argv) {
IRubyObject _str = argv[0];

RubyString str = _str.convertToString();

if (str.getEncoding().isAsciiCompatible()) {
IRubyObject enc = accept_charset(argv, argv.length - 1, 1, self);
return optimized_unescape(context, str, enc, false);
} else {
return Helpers.invokeSuper(context, self, argv, Block.NULL_BLOCK);
}
Expand Down

0 comments on commit 04498c7

Please sign in to comment.