123456789_123456789_123456789_123456789_123456789_

Module: CGI::Escape

Relationships & Source Files
Extension / Inclusion / Inheritance Descendants
Extended In:
Included In:
Defined in: lib/cgi/escape.rb,
ext/cgi/escape/escape.c,
lib/cgi/escape.rb

Overview

Web-related escape/unescape functionality.

Constant Summary

  • TABLE_FOR_ESCAPE_HTML__ = Internal use only

    The set of special characters and their escaped values

    # File 'lib/cgi/escape.rb', line 80
    { # :nodoc:
      "'" => ''',
      '&' => '&',
      '"' => '"',
      '<' => '&lt;',
      '>' => '&gt;',
    }

Instance Method Summary

Instance Method Details

#escape(string)

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"

[ GitHub ]

  
# File 'lib/cgi/escape.rb', line 28

def escape(string)
  encoding = string.encoding
  buffer = string.b
  buffer.gsub!(/([^ a-zA-Z0-9_.\-~]+)/) do |m|
    '%' + m.unpack('H2' * m.bytesize).join('%').upcase
  end
  buffer.tr!(' ', '+')
  buffer.force_encoding(encoding)
end

#escape_element(string, *elements)

Alias for #escapeElement.

[ GitHub ]

  
# File 'lib/cgi/escape.rb', line 229

alias escape_element escapeElement

#escape_uri_component(string)

Alias for #escapeURIComponent.

[ GitHub ]

  
# File 'lib/cgi/escape.rb', line 63

alias escape_uri_component escapeURIComponent

#escapeElement(string, *elements) Also known as: #escape_element

Escape only the tags of certain HTML elements in string.

Takes an element or elements or array of elements. Each element is specified by the name of the element, without angle brackets. This matches both the start and the end tag of that element. 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")
# "<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt"

print CGI.escapeElement('<BR><A HREF="url"></A>', ["A", "IMG"])
# "<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt"
[ GitHub ]

  
# File 'lib/cgi/escape.rb', line 198

def escapeElement(string, *elements)
  elements = elements[0] if elements[0].kind_of?(Array)
  unless elements.empty?
    string.gsub(/<\/?(?:#{elements.join("|")})\b[^<>]*+>?/im) do
      CGI.escapeHTML($&)
    end
  else
    string
  end
end

#escapeHTML(string)

Escape special characters in HTML, namely '&"<> CGI.escapeHTML('Usage: foo "bar" ') # => "Usage: foo "bar" <baz>"

[ GitHub ]

  
# File 'lib/cgi/escape.rb', line 91

def escapeHTML(string)
  enc = string.encoding
  unless enc.ascii_compatible?
    if enc.dummy?
      origenc = enc
      enc = Encoding::Converter.asciicompat_encoding(enc)
      string = enc ? string.encode(enc) : string.b
    end
    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)
  end
end

#escapeURIComponent(string) Also known as: #escape_uri_component

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"

[ GitHub ]

  
# File 'lib/cgi/escape.rb', line 55

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

#unescape(string, encoding = @@accept_charset)

URL-decode an application/x-www-form-urlencoded string with encoding(optional). string = CGI.unescape("%27Stop%21%27+said+Fred") # => "'Stop!' said Fred"

[ GitHub ]

  
# File 'lib/cgi/escape.rb', line 41

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

#unescape_element(string, *elements)

Alias for #unescapeElement.

[ GitHub ]

  
# File 'lib/cgi/escape.rb', line 231

alias unescape_element unescapeElement

#unescape_uri_component(string, encoding = @@accept_charset)

[ GitHub ]

  
# File 'lib/cgi/escape.rb', line 77

alias unescape_uri_component unescapeURIComponent

#unescapeElement(string, *elements) Also known as: #unescape_element

Undo escaping such as that done by CGI.escapeElement

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"])
# "&lt;BR&gt;<A HREF="url"></A>"
[ GitHub ]

  
# File 'lib/cgi/escape.rb', line 218

def unescapeElement(string, *elements)
  elements = elements[0] if elements[0].kind_of?(Array)
  unless elements.empty?
    string.gsub(/&lt;\/?(?:#{elements.join("|")})\b(?>[^&]|&(?![gl]t;)\w;)*(?:&gt;)?/im) do
      unescapeHTML($&)
    end
  else
    string
  end
end

#unescapeHTML(string)

Unescape a string that has been HTML-escaped CGI.unescapeHTML("Usage: foo "bar" <baz>") # => "Usage: foo "bar" "

[ GitHub ]

  
# File 'lib/cgi/escape.rb', line 113

def unescapeHTML(string)
  enc = string.encoding
  unless enc.ascii_compatible?
    if enc.dummy?
      origenc = enc
      enc = Encoding::Converter.asciicompat_encoding(enc)
      string = enc ? string.encode(enc) : string.b
    end
    string = string.gsub(Regexp.new('&(apos|amp|quot|gt|lt|#[0-9]|#x[0-9A-Fa-f]);'.encode(enc))) do
      case $1.encode(Encoding::US_ASCII)
      when 'apos'                then "'".encode(enc)
      when 'amp'                 then '&'.encode(enc)
      when 'quot'                then '"'.encode(enc)
      when 'gt'                  then '>'.encode(enc)
      when 'lt'                  then '<'.encode(enc)
      when /\A#0*(\d+)\z/        then $1.to_i.chr(enc)
      when /\A#x([0-9a-f]+)\z/i  then $1.hex.chr(enc)
      end
    end
    string.encode!(origenc) if origenc
    return string
  end
  return string unless string.include? '&'
  charlimit = case enc
              when Encoding::UTF_8; 0x10ffff
              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
    match = $1
    case match
    when 'apos'                then "'"
    when 'amp'                 then '&'
    when 'quot'                then '"'
    when 'gt'                  then '>'
    when 'lt'                  then '<'
    else
      # Numeric character reference. Decode into the binary buffer so that a
      # non-ASCII byte already present in it never triggers an encoding
      # compatibility error on concatenation; the trailing force_encoding
      # re-tags the whole buffer. This mirrors the C extension's
      # optimized_unescape_html.
      n = match.start_with?('#x', '#X') ? match[2..-1].hex : match[1..-1].to_i
      if n >= charlimit
        "&#{match};"            # out of range: keep the reference verbatim
      elsif charlimit > 256
        [n].pack('U').b         # UTF-8: code point bytes, surrogates included (like rb_enc_mbcput)
      else
        n.chr.b                 # ISO-8859-1 / ASCII: single byte
      end
    end
  end
  string.force_encoding enc
end

#unescapeURIComponent(string, encoding = @@accept_charset) Also known as: #unescape_uri_component

URL-decode a string following RFC 3986 with encoding(optional). string = CGI.unescapeURIComponent("%27Stop%21%27+said%20Fred") # => "'Stop!'+said Fred"

[ GitHub ]

  
# File 'lib/cgi/escape.rb', line 68

def unescapeURIComponent(string, encoding = @@accept_charset)
  str = string.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