summaryrefslogtreecommitdiff
path: root/lib/cgi
diff options
context:
space:
mode:
Diffstat (limited to 'lib/cgi')
-rw-r--r--lib/cgi/cgi.gemspec42
-rw-r--r--lib/cgi/cookie.rb57
-rw-r--r--lib/cgi/core.rb78
-rw-r--r--lib/cgi/html.rb6
-rw-r--r--lib/cgi/session.rb72
-rw-r--r--lib/cgi/session/pstore.rb19
-rw-r--r--lib/cgi/util.rb121
7 files changed, 135 insertions, 260 deletions
diff --git a/lib/cgi/cgi.gemspec b/lib/cgi/cgi.gemspec
deleted file mode 100644
index 381c55a5ca..0000000000
--- a/lib/cgi/cgi.gemspec
+++ /dev/null
@@ -1,42 +0,0 @@
-# frozen_string_literal: true
-
-name = File.basename(__FILE__, ".gemspec")
-version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
- end rescue nil
-end
-
-Gem::Specification.new do |spec|
- spec.name = name
- spec.version = version
- spec.authors = ["Yukihiro Matsumoto"]
- spec.email = ["matz@ruby-lang.org"]
-
- spec.summary = %q{Support for the Common Gateway Interface protocol.}
- spec.description = %q{Support for the Common Gateway Interface protocol.}
- spec.homepage = "https://github.com/ruby/cgi"
- spec.licenses = ["Ruby", "BSD-2-Clause"]
- spec.required_ruby_version = ">= 2.5.0"
-
- spec.metadata["homepage_uri"] = spec.homepage
- spec.metadata["source_code_uri"] = spec.homepage
-
- spec.executables = []
-
- spec.files = [
- "LICENSE.txt",
- "README.md",
- *Dir["lib{.rb,/**/*.rb}", "bin/*"] ]
-
- spec.require_paths = ["lib"]
-
- if Gem::Platform === spec.platform and spec.platform =~ 'java' or RUBY_ENGINE == 'jruby'
- spec.platform = 'java'
- spec.require_paths << "ext/java/org/jruby/ext/cgi/escape/lib"
- spec.files += Dir["ext/java/**/*.{rb}", "lib/cgi/escape.jar"]
- else
- spec.files += Dir["ext/cgi/**/*.{rb,c,h,sh}", "ext/cgi/escape/depend", "lib/cgi/escape.so"]
- spec.extensions = ["ext/cgi/escape/extconf.rb"]
- end
-end
diff --git a/lib/cgi/cookie.rb b/lib/cgi/cookie.rb
index 9498e2f9fa..a2155edb77 100644
--- a/lib/cgi/cookie.rb
+++ b/lib/cgi/cookie.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require_relative 'util'
+require 'cgi/util'
class CGI
# Class representing an HTTP cookie.
#
@@ -40,10 +40,6 @@ class CGI
class Cookie < Array
@@accept_charset="UTF-8" unless defined?(@@accept_charset)
- TOKEN_RE = %r"\A[[!-~]&&[^()<>@,;:\\\"/?=\[\]{}]]+\z"
- PATH_VALUE_RE = %r"\A[[ -~]&&[^;]]*\z"
- DOMAIN_VALUE_RE = %r"\A\.?(?<label>(?!-)[-A-Za-z0-9]+(?<!-))(?:\.\g<label>)*\z"
-
# Create a new CGI::Cookie object.
#
# :call-seq:
@@ -61,7 +57,7 @@ class CGI
#
# name:: the name of the cookie. Required.
# value:: the cookie's value or list of values.
- # path:: the path for which this cookie applies. Defaults to
+ # path:: the path for which this cookie applies. Defaults to the
# the value of the +SCRIPT_NAME+ environment variable.
# domain:: the domain for which this cookie applies.
# expires:: the time at which this cookie expires, as a +Time+ object.
@@ -76,8 +72,9 @@ class CGI
@domain = nil
@expires = nil
if name.kind_of?(String)
- self.name = name
- self.path = (%r|\A(.*/)| =~ ENV["SCRIPT_NAME"] ? $1 : "")
+ @name = name
+ %r|^(.*/)|.match(ENV["SCRIPT_NAME"])
+ @path = ($1 or "")
@secure = false
@httponly = false
return super(value)
@@ -88,11 +85,16 @@ class CGI
raise ArgumentError, "`name' required"
end
- self.name = options["name"]
+ @name = options["name"]
value = Array(options["value"])
# simple support for IE
- self.path = options["path"] || (%r|\A(.*/)| =~ ENV["SCRIPT_NAME"] ? $1 : "")
- self.domain = options["domain"]
+ if options["path"]
+ @path = options["path"]
+ else
+ %r|^(.*/)|.match(ENV["SCRIPT_NAME"])
+ @path = ($1 or "")
+ end
+ @domain = options["domain"]
@expires = options["expires"]
@secure = options["secure"] == true
@httponly = options["httponly"] == true
@@ -101,35 +103,11 @@ class CGI
end
# Name of this cookie, as a +String+
- attr_reader :name
- # Set name of this cookie
- def name=(str)
- if str and !TOKEN_RE.match?(str)
- raise ArgumentError, "invalid name: #{str.dump}"
- end
- @name = str
- end
-
+ attr_accessor :name
# Path for which this cookie applies, as a +String+
- attr_reader :path
- # Set path for which this cookie applies
- def path=(str)
- if str and !PATH_VALUE_RE.match?(str)
- raise ArgumentError, "invalid path: #{str.dump}"
- end
- @path = str
- end
-
+ attr_accessor :path
# Domain for which this cookie applies, as a +String+
- attr_reader :domain
- # Set domain for which this cookie applies
- def domain=(str)
- if str and ((str = str.b).bytesize > 255 or !DOMAIN_VALUE_RE.match?(str))
- raise ArgumentError, "invalid domain: #{str.dump}"
- end
- @domain = str
- end
-
+ attr_accessor :domain
# Time at which this cookie expires, as a +Time+
attr_accessor :expires
# True if this cookie is secure; false otherwise
@@ -168,7 +146,7 @@ class CGI
buf = "#{@name}=#{val}".dup
buf << "; domain=#{@domain}" if @domain
buf << "; path=#{@path}" if @path
- buf << "; expires=#{CGI.rfc1123_date(@expires)}" if @expires
+ buf << "; expires=#{CGI::rfc1123_date(@expires)}" if @expires
buf << "; secure" if @secure
buf << "; HttpOnly" if @httponly
buf
@@ -187,6 +165,7 @@ class CGI
raw_cookie.split(/;\s?/).each do |pairs|
name, values = pairs.split('=',2)
next unless name and values
+ name = CGI.unescape(name)
values ||= ""
values = values.split('&').collect{|v| CGI.unescape(v,@@accept_charset) }
if cookies.has_key?(name)
diff --git a/lib/cgi/core.rb b/lib/cgi/core.rb
index 62e606837a..73daae3e17 100644
--- a/lib/cgi/core.rb
+++ b/lib/cgi/core.rb
@@ -188,28 +188,17 @@ class CGI
# Using #header with the HTML5 tag maker will create a <header> element.
alias :header :http_header
- def _no_crlf_check(str)
- if str
- str = str.to_s
- raise "A HTTP status or header field must not include CR and LF" if str =~ /[\r\n]/
- str
- else
- nil
- end
- end
- private :_no_crlf_check
-
def _header_for_string(content_type) #:nodoc:
buf = ''.dup
if nph?()
- buf << "#{_no_crlf_check($CGI_ENV['SERVER_PROTOCOL']) || 'HTTP/1.0'} 200 OK#{EOL}"
+ buf << "#{$CGI_ENV['SERVER_PROTOCOL'] || 'HTTP/1.0'} 200 OK#{EOL}"
buf << "Date: #{CGI.rfc1123_date(Time.now)}#{EOL}"
- buf << "Server: #{_no_crlf_check($CGI_ENV['SERVER_SOFTWARE'])}#{EOL}"
+ buf << "Server: #{$CGI_ENV['SERVER_SOFTWARE']}#{EOL}"
buf << "Connection: close#{EOL}"
end
- buf << "Content-Type: #{_no_crlf_check(content_type)}#{EOL}"
+ buf << "Content-Type: #{content_type}#{EOL}"
if @output_cookies
- @output_cookies.each {|cookie| buf << "Set-Cookie: #{_no_crlf_check(cookie)}#{EOL}" }
+ @output_cookies.each {|cookie| buf << "Set-Cookie: #{cookie}#{EOL}" }
end
return buf
end # _header_for_string
@@ -224,9 +213,9 @@ class CGI
## NPH
options.delete('nph') if defined?(MOD_RUBY)
if options.delete('nph') || nph?()
- protocol = _no_crlf_check($CGI_ENV['SERVER_PROTOCOL']) || 'HTTP/1.0'
+ protocol = $CGI_ENV['SERVER_PROTOCOL'] || 'HTTP/1.0'
status = options.delete('status')
- status = HTTP_STATUS[status] || _no_crlf_check(status) || '200 OK'
+ status = HTTP_STATUS[status] || status || '200 OK'
buf << "#{protocol} #{status}#{EOL}"
buf << "Date: #{CGI.rfc1123_date(Time.now)}#{EOL}"
options['server'] ||= $CGI_ENV['SERVER_SOFTWARE'] || ''
@@ -234,45 +223,45 @@ class CGI
end
## common headers
status = options.delete('status')
- buf << "Status: #{HTTP_STATUS[status] || _no_crlf_check(status)}#{EOL}" if status
+ buf << "Status: #{HTTP_STATUS[status] || status}#{EOL}" if status
server = options.delete('server')
- buf << "Server: #{_no_crlf_check(server)}#{EOL}" if server
+ buf << "Server: #{server}#{EOL}" if server
connection = options.delete('connection')
- buf << "Connection: #{_no_crlf_check(connection)}#{EOL}" if connection
+ buf << "Connection: #{connection}#{EOL}" if connection
type = options.delete('type')
- buf << "Content-Type: #{_no_crlf_check(type)}#{EOL}" #if type
+ buf << "Content-Type: #{type}#{EOL}" #if type
length = options.delete('length')
- buf << "Content-Length: #{_no_crlf_check(length)}#{EOL}" if length
+ buf << "Content-Length: #{length}#{EOL}" if length
language = options.delete('language')
- buf << "Content-Language: #{_no_crlf_check(language)}#{EOL}" if language
+ buf << "Content-Language: #{language}#{EOL}" if language
expires = options.delete('expires')
buf << "Expires: #{CGI.rfc1123_date(expires)}#{EOL}" if expires
## cookie
if cookie = options.delete('cookie')
case cookie
when String, Cookie
- buf << "Set-Cookie: #{_no_crlf_check(cookie)}#{EOL}"
+ buf << "Set-Cookie: #{cookie}#{EOL}"
when Array
arr = cookie
- arr.each {|c| buf << "Set-Cookie: #{_no_crlf_check(c)}#{EOL}" }
+ arr.each {|c| buf << "Set-Cookie: #{c}#{EOL}" }
when Hash
hash = cookie
- hash.each_value {|c| buf << "Set-Cookie: #{_no_crlf_check(c)}#{EOL}" }
+ hash.each_value {|c| buf << "Set-Cookie: #{c}#{EOL}" }
end
end
if @output_cookies
- @output_cookies.each {|c| buf << "Set-Cookie: #{_no_crlf_check(c)}#{EOL}" }
+ @output_cookies.each {|c| buf << "Set-Cookie: #{c}#{EOL}" }
end
## other headers
options.each do |key, value|
- buf << "#{_no_crlf_check(key)}: #{_no_crlf_check(value)}#{EOL}"
+ buf << "#{key}: #{value}#{EOL}"
end
return buf
end # _header_for_hash
private :_header_for_hash
def nph? #:nodoc:
- return /IIS\/(\d+)/ =~ $CGI_ENV['SERVER_SOFTWARE'] && $1.to_i < 5
+ return /IIS\/(\d+)/.match($CGI_ENV['SERVER_SOFTWARE']) && $1.to_i < 5
end
def _header_for_modruby(buf) #:nodoc:
@@ -386,14 +375,14 @@ class CGI
# Parse an HTTP query string into a hash of key=>value pairs.
#
- # params = CGI.parse("query_string")
+ # params = CGI::parse("query_string")
# # {"name1" => ["value1", "value2", ...],
# # "name2" => ["value1", "value2", ...], ... }
#
- def self.parse(query)
+ def CGI::parse(query)
params = {}
query.split(/[&;]/).each do |pairs|
- key, value = pairs.split('=',2).collect{|v| CGI.unescape(v) }
+ key, value = pairs.split('=',2).collect{|v| CGI::unescape(v) }
next unless key
@@ -432,7 +421,7 @@ class CGI
module QueryExtension
%w[ CONTENT_LENGTH SERVER_PORT ].each do |env|
- define_method(env.delete_prefix('HTTP_').downcase) do
+ define_method(env.sub(/^HTTP_/, '').downcase) do
(val = env_table[env]) && Integer(val)
end
end
@@ -445,7 +434,7 @@ class CGI
HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING
HTTP_ACCEPT_LANGUAGE HTTP_CACHE_CONTROL HTTP_FROM HTTP_HOST
HTTP_NEGOTIATE HTTP_PRAGMA HTTP_REFERER HTTP_USER_AGENT ].each do |env|
- define_method(env.delete_prefix('HTTP_').downcase) do
+ define_method(env.sub(/^HTTP_/, '').downcase) do
env_table[env]
end
end
@@ -555,11 +544,11 @@ class CGI
/Content-Disposition:.* filename=(?:"(.*?)"|([^;\r\n]*))/i.match(head)
filename = $1 || $2 || ''.dup
filename = CGI.unescape(filename) if unescape_filename?()
- body.instance_variable_set(:@original_filename, filename)
+ body.instance_variable_set(:@original_filename, filename.taint)
## content type
/Content-Type: (.*)/i.match(head)
(content_type = $1 || ''.dup).chomp!
- body.instance_variable_set(:@content_type, content_type)
+ body.instance_variable_set(:@content_type, content_type.taint)
## query parameter name
/Content-Disposition:.* name=(?:"(.*?)"|([^;\r\n]*))/i.match(head)
name = $1 || $2 || ''
@@ -618,7 +607,6 @@ class CGI
end
def unescape_filename? #:nodoc:
user_agent = $CGI_ENV['HTTP_USER_AGENT']
- return false unless user_agent
return /Mac/i.match(user_agent) && /Mozilla/i.match(user_agent) && !/MSIE/i.match(user_agent)
end
@@ -660,7 +648,7 @@ class CGI
# Reads query parameters in the @params field, and cookies into @cookies.
def initialize_query()
if ("POST" == env_table['REQUEST_METHOD']) and
- %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?| =~ env_table['CONTENT_TYPE']
+ %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|.match(env_table['CONTENT_TYPE'])
current_max_multipart_length = @max_multipart_length.respond_to?(:call) ? @max_multipart_length.call : @max_multipart_length
raise StandardError.new("too large multipart data.") if env_table['CONTENT_LENGTH'].to_i > current_max_multipart_length
boundary = $1.dup
@@ -668,7 +656,7 @@ class CGI
@params = read_multipart(boundary, Integer(env_table['CONTENT_LENGTH']))
else
@multipart = false
- @params = CGI.parse(
+ @params = CGI::parse(
case env_table['REQUEST_METHOD']
when "GET", "HEAD"
if defined?(MOD_RUBY)
@@ -698,7 +686,7 @@ class CGI
end
end
- @cookies = CGI::Cookie.parse((env_table['HTTP_COOKIE'] or env_table['COOKIE']))
+ @cookies = CGI::Cookie::parse((env_table['HTTP_COOKIE'] or env_table['COOKIE']))
end
private :initialize_query
@@ -874,24 +862,24 @@ class CGI
case @options[:tag_maker]
when "html3"
- require_relative 'html'
+ require 'cgi/html'
extend Html3
extend HtmlExtension
when "html4"
- require_relative 'html'
+ require 'cgi/html'
extend Html4
extend HtmlExtension
when "html4Tr"
- require_relative 'html'
+ require 'cgi/html'
extend Html4Tr
extend HtmlExtension
when "html4Fr"
- require_relative 'html'
+ require 'cgi/html'
extend Html4Tr
extend Html4Fr
extend HtmlExtension
when "html5"
- require_relative 'html'
+ require 'cgi/html'
extend Html5
extend HtmlExtension
end
diff --git a/lib/cgi/html.rb b/lib/cgi/html.rb
index 1543943320..02d847ebd3 100644
--- a/lib/cgi/html.rb
+++ b/lib/cgi/html.rb
@@ -30,10 +30,10 @@ class CGI
attributes.each do|name, value|
next unless value
s << " "
- s << CGI.escapeHTML(name.to_s)
+ s << CGI::escapeHTML(name.to_s)
if value != true
s << '="'
- s << CGI.escapeHTML(value.to_s)
+ s << CGI::escapeHTML(value.to_s)
s << '"'
end
end
@@ -423,7 +423,7 @@ class CGI
buf << super(attributes)
if pretty
- CGI.pretty(buf, pretty)
+ CGI::pretty(buf, pretty)
else
buf
end
diff --git a/lib/cgi/session.rb b/lib/cgi/session.rb
index aab60869bb..fbb42986a4 100644
--- a/lib/cgi/session.rb
+++ b/lib/cgi/session.rb
@@ -189,47 +189,6 @@ class CGI
end
private :create_new_id
-
- # Create a new file to store the session data.
- #
- # This file will be created if it does not exist, or opened if it
- # does.
- #
- # This path is generated under _tmpdir_ from _prefix_, the
- # digested session id, and _suffix_.
- #
- # +option+ is a hash of options for the initializer. The
- # following options are recognised:
- #
- # tmpdir:: the directory to use for storing the FileStore
- # file. Defaults to Dir::tmpdir (generally "/tmp"
- # on Unix systems).
- # prefix:: the prefix to add to the session id when generating
- # the filename for this session's FileStore file.
- # Defaults to "cgi_sid_".
- # suffix:: the prefix to add to the session id when generating
- # the filename for this session's FileStore file.
- # Defaults to the empty string.
- def new_store_file(option={}) # :nodoc:
- dir = option['tmpdir'] || Dir::tmpdir
- prefix = option['prefix']
- suffix = option['suffix']
- require 'digest/md5'
- md5 = Digest::MD5.hexdigest(session_id)[0,16]
- path = dir+"/"
- path << prefix if prefix
- path << md5
- path << suffix if suffix
- if File::exist? path
- hash = nil
- elsif new_session
- hash = {}
- else
- raise NoSession, "uninitialized session"
- end
- return path, hash
- end
-
# Create a new CGI::Session object for +request+.
#
# +request+ is an instance of the +CGI+ class (see cgi.rb).
@@ -279,7 +238,7 @@ class CGI
# fields are surrounded by a <fieldset> tag in HTML 4 generation, which
# is _not_ invisible on many browsers; you may wish to disable the
# use of fieldsets with code similar to the following
- # (see https://blade.ruby-lang.org/ruby-list/37805)
+ # (see http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/37805)
#
# cgi = CGI.new("html4")
# class << cgi
@@ -414,8 +373,21 @@ class CGI
# This session's FileStore file will be created if it does
# not exist, or opened if it does.
def initialize(session, option={})
- option = {'prefix' => 'cgi_sid_'}.update(option)
- @path, @hash = session.new_store_file(option)
+ dir = option['tmpdir'] || Dir::tmpdir
+ prefix = option['prefix'] || 'cgi_sid_'
+ suffix = option['suffix'] || ''
+ id = session.session_id
+ require 'digest/md5'
+ md5 = Digest::MD5.hexdigest(id)[0,16]
+ @path = dir+"/"+prefix+md5+suffix
+ if File::exist? @path
+ @hash = nil
+ else
+ unless session.new_session
+ raise CGI::Session::NoSession, "uninitialized session"
+ end
+ @hash = {}
+ end
end
# Restore session state from the session's FileStore file.
@@ -431,11 +403,11 @@ class CGI
for line in f
line.chomp!
k, v = line.split('=',2)
- @hash[CGI.unescape(k)] = Marshal.restore(CGI.unescape(v))
+ @hash[CGI::unescape(k)] = Marshal.restore(CGI::unescape(v))
end
ensure
- f&.close
- lockf&.close
+ f.close unless f.nil?
+ lockf.close if lockf
end
end
@hash
@@ -449,13 +421,13 @@ class CGI
lockf.flock File::LOCK_EX
f = File.open(@path+".new", File::CREAT|File::TRUNC|File::WRONLY, 0600)
for k,v in @hash
- f.printf "%s=%s\n", CGI.escape(k), CGI.escape(String(Marshal.dump(v)))
+ f.printf "%s=%s\n", CGI::escape(k), CGI::escape(String(Marshal.dump(v)))
end
f.close
File.rename @path+".new", @path
ensure
- f&.close
- lockf&.close
+ f.close if f
+ lockf.close if lockf
end
end
diff --git a/lib/cgi/session/pstore.rb b/lib/cgi/session/pstore.rb
index 45d0d8ae2c..cb0370b619 100644
--- a/lib/cgi/session/pstore.rb
+++ b/lib/cgi/session/pstore.rb
@@ -10,7 +10,7 @@
# persistent of session data on top of the pstore library. See
# cgi/session.rb for more details on session storage managers.
-require_relative '../session'
+require 'cgi/session'
require 'pstore'
class CGI
@@ -44,8 +44,21 @@ class CGI
# This session's PStore file will be created if it does
# not exist, or opened if it does.
def initialize(session, option={})
- option = {'suffix'=>''}.update(option)
- path, @hash = session.new_store_file(option)
+ dir = option['tmpdir'] || Dir::tmpdir
+ prefix = option['prefix'] || ''
+ id = session.session_id
+ require 'digest/md5'
+ md5 = Digest::MD5.hexdigest(id)[0,16]
+ path = dir+"/"+prefix+md5
+ path.untaint
+ if File::exist?(path)
+ @hash = nil
+ else
+ unless session.new_session
+ raise CGI::Session::NoSession, "uninitialized session"
+ end
+ @hash = {}
+ end
@p = ::PStore.new(path)
@p.transaction do |p|
File.chmod(0600, p.path)
diff --git a/lib/cgi/util.rb b/lib/cgi/util.rb
index 4986e544e0..464115262f 100644
--- a/lib/cgi/util.rb
+++ b/lib/cgi/util.rb
@@ -5,63 +5,27 @@ class CGI
extend Util
end
module CGI::Util
- @@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")
+ @@accept_charset="UTF-8" unless defined?(@@accept_charset)
+ # URL-encode a string.
+ # url_encoded_string = CGI::escape("'Stop!' said Fred")
# # => "%27Stop%21%27+said+Fred"
def escape(string)
encoding = string.encoding
- buffer = string.b
- buffer.gsub!(/([^ a-zA-Z0-9_.\-~]+)/) do |m|
+ string.b.gsub(/([^ a-zA-Z0-9_.\-~]+)/) do |m|
'%' + m.unpack('H2' * m.bytesize).join('%').upcase
- end
- buffer.tr!(' ', '+')
- buffer.force_encoding(encoding)
+ end.tr(' ', '+').force_encoding(encoding)
end
- # URL-decode an application/x-www-form-urlencoded string with encoding(optional).
- # string = CGI.unescape("%27Stop%21%27+said+Fred")
+ # URL-decode a string with encoding(optional).
+ # string = CGI::unescape("%27Stop%21%27+said+Fred")
# # => "'Stop!' said Fred"
- 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.escapeURIComponent("'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
- alias escape_uri_component escapeURIComponent
-
- # URL-decode a string following RFC 3986 with encoding(optional).
- # string = CGI.unescapeURIComponent("%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|
+ def unescape(string,encoding=@@accept_charset)
+ str=string.tr('+', ' ').b.gsub(/((?:%[0-9a-fA-F]{2})+)/) do |m|
[m.delete('%')].pack('H*')
- end
- str.force_encoding(encoding)
+ end.force_encoding(encoding)
str.valid_encoding? ? str : str.force_encoding(string.encoding)
end
- alias unescape_uri_component unescapeURIComponent
-
# The set of special characters and their escaped values
TABLE_FOR_ESCAPE_HTML__ = {
"'" => '&#39;',
@@ -72,7 +36,7 @@ module CGI::Util
}
# Escape special characters in HTML, namely '&\"<>
- # CGI.escapeHTML('Usage: foo "bar" <baz>')
+ # CGI::escapeHTML('Usage: foo "bar" <baz>')
# # => "Usage: foo &quot;bar&quot; &lt;baz&gt;"
def escapeHTML(string)
enc = string.encoding
@@ -85,24 +49,18 @@ module CGI::Util
table = Hash[TABLE_FOR_ESCAPE_HTML__.map {|pair|pair.map {|s|s.encode(enc)}}]
string = string.gsub(/#{"['&\"<>]".encode(enc)}/, table)
string.encode!(origenc) if origenc
- string
- else
- string = string.b
- string.gsub!(/['&\"<>]/, TABLE_FOR_ESCAPE_HTML__)
- string.force_encoding(enc)
+ return string
end
+ string.gsub(/['&\"<>]/, TABLE_FOR_ESCAPE_HTML__)
end
- # TruffleRuby runs the pure-Ruby variant faster, do not use the C extension there
- unless RUBY_ENGINE == 'truffleruby'
- begin
- require 'cgi/escape'
- rescue LoadError
- end
+ begin
+ require 'cgi/escape'
+ rescue LoadError
end
# Unescape a string that has been HTML-escaped
- # CGI.unescapeHTML("Usage: foo &quot;bar&quot; &lt;baz&gt;")
+ # CGI::unescapeHTML("Usage: foo &quot;bar&quot; &lt;baz&gt;")
# # => "Usage: foo \"bar\" <baz>"
def unescapeHTML(string)
enc = string.encoding
@@ -132,8 +90,7 @@ module CGI::Util
when Encoding::ISO_8859_1; 256
else 128
end
- string = string.b
- string.gsub!(/&(apos|amp|quot|gt|lt|\#[0-9]+|\#[xX][0-9A-Fa-f]+);/) do
+ string.gsub(/&(apos|amp|quot|gt|lt|\#[0-9]+|\#[xX][0-9A-Fa-f]+);/) do
match = $1.dup
case match
when 'apos' then "'"
@@ -159,13 +116,12 @@ module CGI::Util
"&#{match};"
end
end
- string.force_encoding enc
end
- # Synonym for CGI.escapeHTML(str)
+ # Synonym for CGI::escapeHTML(str)
alias escape_html escapeHTML
- # Synonym for CGI.unescapeHTML(str)
+ # Synonym for CGI::unescapeHTML(str)
alias unescape_html unescapeHTML
# Escape only the tags of certain HTML elements in +string+.
@@ -176,30 +132,30 @@ module CGI::Util
# The attribute list of the open tag will also be escaped (for
# instance, the double-quotes surrounding attribute values).
#
- # print CGI.escapeElement('<BR><A HREF="url"></A>', "A", "IMG")
+ # print CGI::escapeElement('<BR><A HREF="url"></A>', "A", "IMG")
# # "<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt"
#
- # print CGI.escapeElement('<BR><A HREF="url"></A>', ["A", "IMG"])
+ # print CGI::escapeElement('<BR><A HREF="url"></A>', ["A", "IMG"])
# # "<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt"
def escapeElement(string, *elements)
elements = elements[0] if elements[0].kind_of?(Array)
unless elements.empty?
string.gsub(/<\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?>/i) do
- CGI.escapeHTML($&)
+ CGI::escapeHTML($&)
end
else
string
end
end
- # Undo escaping such as that done by CGI.escapeElement()
+ # Undo escaping such as that done by CGI::escapeElement()
#
- # print CGI.unescapeElement(
- # CGI.escapeHTML('<BR><A HREF="url"></A>'), "A", "IMG")
+ # print CGI::unescapeElement(
+ # CGI::escapeHTML('<BR><A HREF="url"></A>'), "A", "IMG")
# # "&lt;BR&gt;<A HREF="url"></A>"
#
- # print CGI.unescapeElement(
- # CGI.escapeHTML('<BR><A HREF="url"></A>'), ["A", "IMG"])
+ # print CGI::unescapeElement(
+ # CGI::escapeHTML('<BR><A HREF="url"></A>'), ["A", "IMG"])
# # "&lt;BR&gt;<A HREF="url"></A>"
def unescapeElement(string, *elements)
elements = elements[0] if elements[0].kind_of?(Array)
@@ -212,18 +168,27 @@ module CGI::Util
end
end
- # Synonym for CGI.escapeElement(str)
+ # Synonym for CGI::escapeElement(str)
alias escape_element escapeElement
- # Synonym for CGI.unescapeElement(str)
+ # Synonym for CGI::unescapeElement(str)
alias unescape_element unescapeElement
+ # Abbreviated day-of-week names specified by RFC 822
+ RFC822_DAYS = %w[ Sun Mon Tue Wed Thu Fri Sat ]
+
+ # Abbreviated month names specified by RFC 822
+ RFC822_MONTHS = %w[ Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ]
+
# Format a +Time+ object as a String using the format specified by RFC 1123.
#
- # CGI.rfc1123_date(Time.now)
+ # CGI::rfc1123_date(Time.now)
# # Sat, 01 Jan 2000 00:00:00 GMT
def rfc1123_date(time)
- time.getgm.strftime("%a, %d %b %Y %T GMT")
+ t = time.clone.gmtime
+ return format("%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT",
+ RFC822_DAYS[t.wday], t.day, RFC822_MONTHS[t.month-1], t.year,
+ t.hour, t.min, t.sec)
end
# Prettify (indent) an HTML string.
@@ -231,13 +196,13 @@ module CGI::Util
# +string+ is the HTML string to indent. +shift+ is the indentation
# unit to use; it defaults to two spaces.
#
- # print CGI.pretty("<HTML><BODY></BODY></HTML>")
+ # print CGI::pretty("<HTML><BODY></BODY></HTML>")
# # <HTML>
# # <BODY>
# # </BODY>
# # </HTML>
#
- # print CGI.pretty("<HTML><BODY></BODY></HTML>", "\t")
+ # print CGI::pretty("<HTML><BODY></BODY></HTML>", "\t")
# # <HTML>
# # <BODY>
# # </BODY>