summaryrefslogtreecommitdiff
path: root/lib/cgi/util.rb
diff options
context:
space:
mode:
authorJean Boussier <jean.boussier@gmail.com>2022-06-09 12:07:58 +0200
committergit <svn-admin@ruby-lang.org>2022-08-16 19:12:03 +0900
commit3850113e20b8c031529fc79de7202f61604425dd (patch)
tree9a6cbd36529b625e1514c768e6cc98efc4886f89 /lib/cgi/util.rb
parent5389c9813b1970a1a5cb2bc8f67b098d38a99d1d (diff)
[ruby/cgi] Implement `CGI.url_encode` and `CGI.url_decode`
[Feature #18822] Ruby is somewhat missing an RFC 3986 compliant escape method. https://github.com/ruby/cgi/commit/c2729c7f33
Diffstat (limited to 'lib/cgi/util.rb')
-rw-r--r--lib/cgi/util.rb49
1 files changed, 41 insertions, 8 deletions
diff --git a/lib/cgi/util.rb b/lib/cgi/util.rb
index 55e61bf984..5a5c77ac97 100644
--- a/lib/cgi/util.rb
+++ b/lib/cgi/util.rb
@@ -5,24 +5,57 @@ class CGI
extend Util
end
module CGI::Util
- @@accept_charset="UTF-8" unless defined?(@@accept_charset)
- # URL-encode a string.
+ @@accept_charset = Encoding::UTF_8 unless defined?(@@accept_charset)
+
+ # URL-encode a string into application/x-www-form-urlencoded.
+ # Space characters (+" "+) are encoded with plus signs (+"+"+)
# url_encoded_string = CGI.escape("'Stop!' said Fred")
# # => "%27Stop%21%27+said+Fred"
def escape(string)
encoding = string.encoding
- string.b.gsub(/([^ a-zA-Z0-9_.\-~]+)/) do |m|
+ buffer = string.b
+ buffer.gsub!(/([^ a-zA-Z0-9_.\-~]+)/) do |m|
'%' + m.unpack('H2' * m.bytesize).join('%').upcase
- end.tr(' ', '+').force_encoding(encoding)
+ end
+ buffer.tr!(' ', '+')
+ buffer.force_encoding(encoding)
end
- # URL-decode a string with encoding(optional).
+ # URL-decode an application/x-www-form-urlencoded string with encoding(optional).
# string = CGI.unescape("%27Stop%21%27+said+Fred")
# # => "'Stop!' said Fred"
- def unescape(string,encoding=@@accept_charset)
- str=string.tr('+', ' ').b.gsub(/((?:%[0-9a-fA-F]{2})+)/) do |m|
+ def unescape(string, encoding = @@accept_charset)
+ str = string.tr('+', ' ')
+ str = str.b
+ str.gsub!(/((?:%[0-9a-fA-F]{2})+)/) do |m|
+ [m.delete('%')].pack('H*')
+ end
+ str.force_encoding(encoding)
+ str.valid_encoding? ? str : str.force_encoding(string.encoding)
+ end
+
+ # URL-encode a string following RFC 3986
+ # Space characters (+" "+) are encoded with (+"%20"+)
+ # url_encoded_string = CGI.escape("'Stop!' said Fred")
+ # # => "%27Stop%21%27%20said%20Fred"
+ def escapeURIComponent(string)
+ encoding = string.encoding
+ buffer = string.b
+ buffer.gsub!(/([^a-zA-Z0-9_.\-~]+)/) do |m|
+ '%' + m.unpack('H2' * m.bytesize).join('%').upcase
+ end
+ buffer.force_encoding(encoding)
+ end
+
+ # URL-decode a string following RFC 3986 with encoding(optional).
+ # string = CGI.unescape("%27Stop%21%27+said%20Fred")
+ # # => "'Stop!'+said Fred"
+ def unescapeURIComponent(string, encoding = @@accept_charset)
+ str = string.b
+ str.gsub!(/((?:%[0-9a-fA-F]{2})+)/) do |m|
[m.delete('%')].pack('H*')
- end.force_encoding(encoding)
+ end
+ str.force_encoding(encoding)
str.valid_encoding? ? str : str.force_encoding(string.encoding)
end