# frozen_string_literal: trueclassCGImoduleUtil;endincludeUtilextendUtilendmoduleCGI::Util@@accept_charset="UTF-8"unlessdefined?(@@accept_charset)# URL-encode a string.# url_encoded_string = CGI.escape("'Stop!' said Fred")# # => "%27Stop%21%27+said+Fred"defescape(string)encoding=string.encodingstring.b.gsub(/([^ a-zA-Z0-9_.\-~]+)/)do|m|'%'+m.unpack('H2'*m.bytesize).join('%').upcaseend.tr(' ','+').force_encoding(encoding)end# URL-decode a string with encoding(optional).# string = CGI.unescape("%27Stop%21%27+said+Fred")# # => "'Stop!' said Fred"defunescape(string,encoding=@@accept_charset)str=string.tr('+',' ').b.gsub(/((?:%[0-9a-fA-F]{2})+)/)do|m|[m.delete('%')].pack('H*')end.force_encoding(encoding)str.valid_encoding??str:str.force_encoding(string.encoding)end# The set of special characters and their escaped valuesTABLE_FOR_ESCAPE_HTML__={"'"=>''','&'=>'&','"'=>'"','<'=>'<','>'=>'>',}# Escape special characters in HTML, namely '&\"<># CGI.escapeHTML('Usage: foo "bar" <baz>')# # => "Usage: foo "bar" <baz>"defescapeHTML(string)enc=string.encodingunlessenc.ascii_compatible?ifenc.dummy?origenc=encenc=Encoding::Converter.asciicompat_encoding(enc)string=enc?string.encode(enc):string.bendtable=Hash[TABLE_FOR_ESCAPE_HTML__.map{|pair|pair.map{|s|s.encode(enc)}}]string=string.gsub(/#{"['&\"<>]".encode(enc)}/,table)string.encode!(origenc)iforigencreturnstringendstring.gsub(/['&\"<>]/,TABLE_FOR_ESCAPE_HTML__)endbeginrequire'cgi/escape'rescueLoadErrorend# Unescape a string that has been HTML-escaped# CGI.unescapeHTML("Usage: foo "bar" <baz>")# # => "Usage: foo \"bar\" <baz>"defunescapeHTML(string)enc=string.encodingunlessenc.ascii_compatible?ifenc.dummy?origenc=encenc=Encoding::Converter.asciicompat_encoding(enc)string=enc?string.encode(enc):string.bendstring=string.gsub(Regexp.new('&(apos|amp|quot|gt|lt|#[0-9]+|#x[0-9A-Fa-f]+);'.encode(enc)))docase$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/ithen$1.hex.chr(enc)endendstring.encode!(origenc)iforigencreturnstringendreturnstringunlessstring.include?'&'charlimit=caseencwhenEncoding::UTF_8;0x10ffffwhenEncoding::ISO_8859_1;256else128endstring.gsub(/&(apos|amp|quot|gt|lt|\#[0-9]+|\#[xX][0-9A-Fa-f]+);/)domatch=$1.dupcasematchwhen'apos'then"'"when'amp'then'&'when'quot'then'"'when'gt'then'>'when'lt'then'<'when/\A#0*(\d+)\z/n=$1.to_iifn<charlimitn.chr(enc)else"&##{$1};"endwhen/\A#x([0-9a-f]+)\z/in=$1.hexifn<charlimitn.chr(enc)else"&#x#{$1};"endelse"&#{match};"endendend# Synonym for CGI.escapeHTML(str)aliasescape_htmlescapeHTML# Synonym for CGI.unescapeHTML(str)aliasunescape_htmlunescapeHTML# 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><A HREF="url"></A>"## print CGI.escapeElement('<BR><A HREF="url"></A>', ["A", "IMG"])# # "<BR><A HREF="url"></A>"defescapeElement(string,*elements)elements=elements[0]ifelements[0].kind_of?(Array)unlesselements.empty?string.gsub(/<\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?>/i)doCGI.escapeHTML($&)endelsestringendend# Undo escaping such as that done by CGI.escapeElement()## print CGI.unescapeElement(# CGI.escapeHTML('<BR><A HREF="url"></A>'), "A", "IMG")# # "<BR><A HREF="url"></A>"## print CGI.unescapeElement(# CGI.escapeHTML('<BR><A HREF="url"></A>'), ["A", "IMG"])# # "<BR><A HREF="url"></A>"defunescapeElement(string,*elements)elements=elements[0]ifelements[0].kind_of?(Array)unlesselements.empty?string.gsub(/<\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?>/i)dounescapeHTML($&)endelsestringendend# Synonym for CGI.escapeElement(str)aliasescape_elementescapeElement# Synonym for CGI.unescapeElement(str)aliasunescape_elementunescapeElement# Abbreviated day-of-week names specified by RFC 822RFC822_DAYS=%w[ Sun Mon Tue Wed Thu Fri Sat ]# Abbreviated month names specified by RFC 822RFC822_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)# # Sat, 01 Jan 2000 00:00:00 GMTdefrfc1123_date(time)t=time.clone.gmtimereturnformat("%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.## +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>")# # <HTML># # <BODY># # </BODY># # </HTML>## print CGI.pretty("<HTML><BODY></BODY></HTML>", "\t")# # <HTML># # <BODY># # </BODY># # </HTML>#defpretty(string,shift=" ")lines=string.gsub(/(?!\A)<.*?>/m,"\n\\0").gsub(/<.*?>(?!\n)/m,"\\0\n")end_pos=0whileend_pos=lines.index(/^<\/(\w+)/,end_pos)element=$1.dupstart_pos=lines.rindex(/^\s*<#{element}/i,end_pos)lines[start_pos...end_pos]="__"+lines[start_pos...end_pos].gsub(/\n(?!\z)/,"\n"+shift)+"__"endlines.gsub(/^((?:#{Regexp::quote(shift)})*)__(?=<\/?\w)/,'\1')endaliashescapeHTMLend