cgi 0.3.7 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 07ab7772a63961e384acc8ba4823973fcc33a2146cca79711c9255f4501afea9
4
- data.tar.gz: ed59bcae676cebc82134bf5244ec08af350091eab8cdbd9767d913035fd57a56
3
+ metadata.gz: 4807bd75c56012fd4b219cd83c6b0fb76006483f176b9a7b19b2658606b11503
4
+ data.tar.gz: b49eebc85d48ac1f068dda9fd36570dbb83d2ee787d6d458680996d29554d8ce
5
5
  SHA512:
6
- metadata.gz: 91a289cd6cfb781acadc05fdb858611a6dbc0f711a8b0b2d84353bfe6e97a2bf0df4b3fadbae829f73f2480ef2d4968bf8a9d7afe509214f6b71bcc9f3088a0f
7
- data.tar.gz: 71d586f04495fe3abd333a0bf5bb4f017b72bd4d40536ac3dae1f7fadd8f61087720d40757b40d69d86b762826192bd406391061835fdc51d709912f1add60ab
6
+ metadata.gz: c85c60cdefbe541dd68ebc7c82be5a62635bb3861e7a717d828cff5e2072c583bdb0722d85eb36d18a6f1a28255cad60f8d2879d302c10c94f4c7e2c3100103f
7
+ data.tar.gz: c7a7fccaf06fed4326df4fb5dc1bcab429e4c1430bffb010f5a3c46a4c1b53c102c32b7142b6bdda1a090d6c152da34cdc76e4f5a1d67e1bd37a6df6fc7b5f8e
@@ -4,10 +4,10 @@ Redistribution and use in source and binary forms, with or without
4
4
  modification, are permitted provided that the following conditions
5
5
  are met:
6
6
  1. Redistributions of source code must retain the above copyright
7
- notice, this list of conditions and the following disclaimer.
7
+ notice, this list of conditions and the following disclaimer.
8
8
  2. Redistributions in binary form must reproduce the above copyright
9
- notice, this list of conditions and the following disclaimer in the
10
- documentation and/or other materials provided with the distribution.
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
11
 
12
12
  THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13
13
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
data/COPYING ADDED
@@ -0,0 +1,56 @@
1
+ Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.jp>.
2
+ You can redistribute it and/or modify it under either the terms of the
3
+ 2-clause BSDL (see the file BSDL), or the conditions below:
4
+
5
+ 1. You may make and give away verbatim copies of the source form of the
6
+ software without restriction, provided that you duplicate all of the
7
+ original copyright notices and associated disclaimers.
8
+
9
+ 2. You may modify your copy of the software in any way, provided that
10
+ you do at least ONE of the following:
11
+
12
+ a. place your modifications in the Public Domain or otherwise
13
+ make them Freely Available, such as by posting said
14
+ modifications to Usenet or an equivalent medium, or by allowing
15
+ the author to include your modifications in the software.
16
+
17
+ b. use the modified software only within your corporation or
18
+ organization.
19
+
20
+ c. give non-standard binaries non-standard names, with
21
+ instructions on where to get the original software distribution.
22
+
23
+ d. make other distribution arrangements with the author.
24
+
25
+ 3. You may distribute the software in object code or binary form,
26
+ provided that you do at least ONE of the following:
27
+
28
+ a. distribute the binaries and library files of the software,
29
+ together with instructions (in the manual page or equivalent)
30
+ on where to get the original distribution.
31
+
32
+ b. accompany the distribution with the machine-readable source of
33
+ the software.
34
+
35
+ c. give non-standard binaries non-standard names, with
36
+ instructions on where to get the original software distribution.
37
+
38
+ d. make other distribution arrangements with the author.
39
+
40
+ 4. You may modify and include the part of the software into any other
41
+ software (possibly commercial). But some files in the distribution
42
+ are not written by the author, so that they are not under these terms.
43
+
44
+ For the list of those files and their copying conditions, see the
45
+ file LEGAL.
46
+
47
+ 5. The scripts and library files supplied as input to or produced as
48
+ output from the software do not automatically fall under the
49
+ copyright of the software, but belong to whomever generated them,
50
+ and may be sold commercially, and may be aggregated with this
51
+ software.
52
+
53
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
54
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
55
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56
+ PURPOSE.
data/README.md CHANGED
@@ -32,21 +32,19 @@ Or install it yourself as:
32
32
 
33
33
  ### Get form values
34
34
 
35
+ Given a form with the content `field_name=123`:
36
+
35
37
  ```ruby
36
38
  require "cgi"
37
39
  cgi = CGI.new
38
- value = cgi['field_name'] # <== value string for 'field_name'
39
- # if not 'field_name' included, then return "".
40
- fields = cgi.keys # <== array of field names
41
-
42
- # returns true if form has 'field_name'
43
- cgi.has_key?('field_name')
44
- cgi.has_key?('field_name')
45
- cgi.include?('field_name')
46
- ```
40
+ value = cgi['field_name'] # => "123"
41
+ cgi['flowerpot'] # => ""
42
+ fields = cgi.keys # => [ "field_name" ]
47
43
 
48
- CAUTION! cgi['field_name'] returned an Array with the old
49
- cgi.rb(included in Ruby 1.6)
44
+ cgi.has_key?('field_name') # => true
45
+ cgi.include?('field_name') # => true
46
+ cgi.include?('flowerpot') # => false
47
+ ```
50
48
 
51
49
  ### Get form values as hash
52
50
 
@@ -8,7 +8,7 @@ RUBY_EXTERN const signed char ruby_digit36_to_number_table[];
8
8
  #define upper_hexdigits (ruby_hexdigits+16)
9
9
  #define char_to_number(c) ruby_digit36_to_number_table[(unsigned char)(c)]
10
10
 
11
- static VALUE rb_cCGI, rb_mUtil, rb_mEscape;
11
+ static VALUE rb_cCGI, rb_mEscape, rb_mEscapeExt;
12
12
  static ID id_accept_charset;
13
13
 
14
14
  #define HTML_ESCAPE_MAX_LEN 6
@@ -83,7 +83,7 @@ optimized_unescape_html(VALUE str)
83
83
  unsigned long charlimit = (strcasecmp(rb_enc_name(enc), "UTF-8") == 0 ? UNICODE_MAX :
84
84
  strcasecmp(rb_enc_name(enc), "ISO-8859-1") == 0 ? 256 :
85
85
  128);
86
- long i, len, beg = 0;
86
+ long i, j, len, beg = 0;
87
87
  size_t clen, plen;
88
88
  int overflow;
89
89
  const char *cstr;
@@ -100,6 +100,7 @@ optimized_unescape_html(VALUE str)
100
100
  plen = i - beg;
101
101
  if (++i >= len) break;
102
102
  c = (unsigned char)cstr[i];
103
+ j = i;
103
104
  #define MATCH(s) (len - i >= (int)rb_strlen_lit(s) && \
104
105
  memcmp(&cstr[i], s, rb_strlen_lit(s)) == 0 && \
105
106
  (i += rb_strlen_lit(s) - 1, 1))
@@ -112,28 +113,40 @@ optimized_unescape_html(VALUE str)
112
113
  else if (MATCH("mp;")) {
113
114
  c = '&';
114
115
  }
115
- else continue;
116
+ else {
117
+ i = j;
118
+ continue;
119
+ }
116
120
  break;
117
121
  case 'q':
118
122
  ++i;
119
123
  if (MATCH("uot;")) {
120
124
  c = '"';
121
125
  }
122
- else continue;
126
+ else {
127
+ i = j;
128
+ continue;
129
+ }
123
130
  break;
124
131
  case 'g':
125
132
  ++i;
126
133
  if (MATCH("t;")) {
127
134
  c = '>';
128
135
  }
129
- else continue;
136
+ else {
137
+ i = j;
138
+ continue;
139
+ }
130
140
  break;
131
141
  case 'l':
132
142
  ++i;
133
143
  if (MATCH("t;")) {
134
144
  c = '<';
135
145
  }
136
- else continue;
146
+ else {
147
+ i = j;
148
+ continue;
149
+ }
137
150
  break;
138
151
  case '#':
139
152
  if (len - ++i >= 2 && ISDIGIT(cstr[i])) {
@@ -142,9 +155,15 @@ optimized_unescape_html(VALUE str)
142
155
  else if ((cstr[i] == 'x' || cstr[i] == 'X') && len - ++i >= 2 && ISXDIGIT(cstr[i])) {
143
156
  cc = ruby_scan_digits(&cstr[i], len-i, 16, &clen, &overflow);
144
157
  }
145
- else continue;
158
+ else {
159
+ i = j;
160
+ continue;
161
+ }
146
162
  i += clen;
147
- if (overflow || cc >= charlimit || cstr[i] != ';') continue;
163
+ if (overflow || cc >= charlimit || cstr[i] != ';') {
164
+ i = j;
165
+ continue;
166
+ }
148
167
  if (!dest) {
149
168
  dest = rb_str_buf_new(len);
150
169
  }
@@ -452,15 +471,17 @@ Init_escape(void)
452
471
  void
453
472
  InitVM_escape(void)
454
473
  {
455
- rb_cCGI = rb_define_class("CGI", rb_cObject);
456
- rb_mEscape = rb_define_module_under(rb_cCGI, "Escape");
457
- rb_mUtil = rb_define_module_under(rb_cCGI, "Util");
458
- rb_define_method(rb_mEscape, "escapeHTML", cgiesc_escape_html, 1);
459
- rb_define_method(rb_mEscape, "unescapeHTML", cgiesc_unescape_html, 1);
460
- rb_define_method(rb_mEscape, "escapeURIComponent", cgiesc_escape_uri_component, 1);
461
- rb_define_method(rb_mEscape, "unescapeURIComponent", cgiesc_unescape_uri_component, -1);
462
- rb_define_method(rb_mEscape, "escape", cgiesc_escape, 1);
463
- rb_define_method(rb_mEscape, "unescape", cgiesc_unescape, -1);
464
- rb_prepend_module(rb_mUtil, rb_mEscape);
465
- rb_extend_object(rb_cCGI, rb_mEscape);
474
+ rb_cCGI = rb_define_class("CGI", rb_cObject);
475
+ rb_mEscapeExt = rb_define_module_under(rb_cCGI, "EscapeExt");
476
+ rb_mEscape = rb_define_module_under(rb_cCGI, "Escape");
477
+ rb_define_method(rb_mEscapeExt, "escapeHTML", cgiesc_escape_html, 1);
478
+ rb_define_method(rb_mEscapeExt, "unescapeHTML", cgiesc_unescape_html, 1);
479
+ rb_define_method(rb_mEscapeExt, "escapeURIComponent", cgiesc_escape_uri_component, 1);
480
+ rb_define_alias(rb_mEscapeExt, "escape_uri_component", "escapeURIComponent");
481
+ rb_define_method(rb_mEscapeExt, "unescapeURIComponent", cgiesc_unescape_uri_component, -1);
482
+ rb_define_alias(rb_mEscapeExt, "unescape_uri_component", "unescapeURIComponent");
483
+ rb_define_method(rb_mEscapeExt, "escape", cgiesc_escape, 1);
484
+ rb_define_method(rb_mEscapeExt, "unescape", cgiesc_unescape, -1);
485
+ rb_prepend_module(rb_mEscape, rb_mEscapeExt);
486
+ rb_extend_object(rb_cCGI, rb_mEscapeExt);
466
487
  }
@@ -1,3 +1,7 @@
1
1
  require 'mkmf'
2
2
 
3
- create_makefile 'cgi/escape'
3
+ if RUBY_ENGINE == 'truffleruby'
4
+ File.write("Makefile", dummy_makefile($srcdir).join(""))
5
+ else
6
+ create_makefile 'cgi/escape'
7
+ end
data/lib/cgi/core.rb CHANGED
@@ -4,12 +4,12 @@
4
4
  # generating HTTP responses.
5
5
  #++
6
6
  class CGI
7
- unless const_defined?(:Util)
8
- module Util
7
+ unless const_defined?(:Escape)
8
+ module Escape
9
9
  @@accept_charset = "UTF-8" # :nodoc:
10
10
  end
11
- include Util
12
- extend Util
11
+ include Escape
12
+ extend Escape
13
13
  end
14
14
 
15
15
  $CGI_ENV = ENV # for FCGI support
data/lib/cgi/escape.rb ADDED
@@ -0,0 +1,224 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CGI
4
+ module Escape; end
5
+ include Escape
6
+ extend Escape
7
+ end
8
+
9
+ module CGI::Escape
10
+ @@accept_charset = Encoding::UTF_8 unless defined?(@@accept_charset)
11
+
12
+ # URL-encode a string into application/x-www-form-urlencoded.
13
+ # Space characters (+" "+) are encoded with plus signs (+"+"+)
14
+ # url_encoded_string = CGI.escape("'Stop!' said Fred")
15
+ # # => "%27Stop%21%27+said+Fred"
16
+ def escape(string)
17
+ encoding = string.encoding
18
+ buffer = string.b
19
+ buffer.gsub!(/([^ a-zA-Z0-9_.\-~]+)/) do |m|
20
+ '%' + m.unpack('H2' * m.bytesize).join('%').upcase
21
+ end
22
+ buffer.tr!(' ', '+')
23
+ buffer.force_encoding(encoding)
24
+ end
25
+
26
+ # URL-decode an application/x-www-form-urlencoded string with encoding(optional).
27
+ # string = CGI.unescape("%27Stop%21%27+said+Fred")
28
+ # # => "'Stop!' said Fred"
29
+ def unescape(string, encoding = @@accept_charset)
30
+ str = string.tr('+', ' ')
31
+ str = str.b
32
+ str.gsub!(/((?:%[0-9a-fA-F]{2})+)/) do |m|
33
+ [m.delete('%')].pack('H*')
34
+ end
35
+ str.force_encoding(encoding)
36
+ str.valid_encoding? ? str : str.force_encoding(string.encoding)
37
+ end
38
+
39
+ # URL-encode a string following RFC 3986
40
+ # Space characters (+" "+) are encoded with (+"%20"+)
41
+ # url_encoded_string = CGI.escapeURIComponent("'Stop!' said Fred")
42
+ # # => "%27Stop%21%27%20said%20Fred"
43
+ def escapeURIComponent(string)
44
+ encoding = string.encoding
45
+ buffer = string.b
46
+ buffer.gsub!(/([^a-zA-Z0-9_.\-~]+)/) do |m|
47
+ '%' + m.unpack('H2' * m.bytesize).join('%').upcase
48
+ end
49
+ buffer.force_encoding(encoding)
50
+ end
51
+ alias escape_uri_component escapeURIComponent
52
+
53
+ # URL-decode a string following RFC 3986 with encoding(optional).
54
+ # string = CGI.unescapeURIComponent("%27Stop%21%27+said%20Fred")
55
+ # # => "'Stop!'+said Fred"
56
+ def unescapeURIComponent(string, encoding = @@accept_charset)
57
+ str = string.b
58
+ str.gsub!(/((?:%[0-9a-fA-F]{2})+)/) do |m|
59
+ [m.delete('%')].pack('H*')
60
+ end
61
+ str.force_encoding(encoding)
62
+ str.valid_encoding? ? str : str.force_encoding(string.encoding)
63
+ end
64
+
65
+ alias unescape_uri_component unescapeURIComponent
66
+
67
+ # The set of special characters and their escaped values
68
+ TABLE_FOR_ESCAPE_HTML__ = {
69
+ "'" => '&#39;',
70
+ '&' => '&amp;',
71
+ '"' => '&quot;',
72
+ '<' => '&lt;',
73
+ '>' => '&gt;',
74
+ }
75
+
76
+ # Escape special characters in HTML, namely '&\"<>
77
+ # CGI.escapeHTML('Usage: foo "bar" <baz>')
78
+ # # => "Usage: foo &quot;bar&quot; &lt;baz&gt;"
79
+ def escapeHTML(string)
80
+ enc = string.encoding
81
+ unless enc.ascii_compatible?
82
+ if enc.dummy?
83
+ origenc = enc
84
+ enc = Encoding::Converter.asciicompat_encoding(enc)
85
+ string = enc ? string.encode(enc) : string.b
86
+ end
87
+ table = Hash[TABLE_FOR_ESCAPE_HTML__.map {|pair|pair.map {|s|s.encode(enc)}}]
88
+ string = string.gsub(/#{"['&\"<>]".encode(enc)}/, table)
89
+ string.encode!(origenc) if origenc
90
+ string
91
+ else
92
+ string = string.b
93
+ string.gsub!(/['&\"<>]/, TABLE_FOR_ESCAPE_HTML__)
94
+ string.force_encoding(enc)
95
+ end
96
+ end
97
+
98
+ # Unescape a string that has been HTML-escaped
99
+ # CGI.unescapeHTML("Usage: foo &quot;bar&quot; &lt;baz&gt;")
100
+ # # => "Usage: foo \"bar\" <baz>"
101
+ def unescapeHTML(string)
102
+ enc = string.encoding
103
+ unless enc.ascii_compatible?
104
+ if enc.dummy?
105
+ origenc = enc
106
+ enc = Encoding::Converter.asciicompat_encoding(enc)
107
+ string = enc ? string.encode(enc) : string.b
108
+ end
109
+ string = string.gsub(Regexp.new('&(apos|amp|quot|gt|lt|#[0-9]+|#x[0-9A-Fa-f]+);'.encode(enc))) do
110
+ case $1.encode(Encoding::US_ASCII)
111
+ when 'apos' then "'".encode(enc)
112
+ when 'amp' then '&'.encode(enc)
113
+ when 'quot' then '"'.encode(enc)
114
+ when 'gt' then '>'.encode(enc)
115
+ when 'lt' then '<'.encode(enc)
116
+ when /\A#0*(\d+)\z/ then $1.to_i.chr(enc)
117
+ when /\A#x([0-9a-f]+)\z/i then $1.hex.chr(enc)
118
+ end
119
+ end
120
+ string.encode!(origenc) if origenc
121
+ return string
122
+ end
123
+ return string unless string.include? '&'
124
+ charlimit = case enc
125
+ when Encoding::UTF_8; 0x10ffff
126
+ when Encoding::ISO_8859_1; 256
127
+ else 128
128
+ end
129
+ string = string.b
130
+ string.gsub!(/&(apos|amp|quot|gt|lt|\#[0-9]+|\#[xX][0-9A-Fa-f]+);/) do
131
+ match = $1.dup
132
+ case match
133
+ when 'apos' then "'"
134
+ when 'amp' then '&'
135
+ when 'quot' then '"'
136
+ when 'gt' then '>'
137
+ when 'lt' then '<'
138
+ when /\A#0*(\d+)\z/
139
+ n = $1.to_i
140
+ if n < charlimit
141
+ n.chr(enc)
142
+ else
143
+ "&##{$1};"
144
+ end
145
+ when /\A#x([0-9a-f]+)\z/i
146
+ n = $1.hex
147
+ if n < charlimit
148
+ n.chr(enc)
149
+ else
150
+ "&#x#{$1};"
151
+ end
152
+ else
153
+ "&#{match};"
154
+ end
155
+ end
156
+ string.force_encoding enc
157
+ end
158
+
159
+ # Synonym for CGI.escapeHTML(str)
160
+ alias escape_html escapeHTML
161
+ alias h escapeHTML
162
+
163
+ # Synonym for CGI.unescapeHTML(str)
164
+ alias unescape_html unescapeHTML
165
+
166
+ # TruffleRuby runs the pure-Ruby variant faster, do not use the C extension there
167
+ unless RUBY_ENGINE == 'truffleruby'
168
+ begin
169
+ require 'cgi/escape.so'
170
+ rescue LoadError
171
+ end
172
+ end
173
+
174
+ # Escape only the tags of certain HTML elements in +string+.
175
+ #
176
+ # Takes an element or elements or array of elements. Each element
177
+ # is specified by the name of the element, without angle brackets.
178
+ # This matches both the start and the end tag of that element.
179
+ # The attribute list of the open tag will also be escaped (for
180
+ # instance, the double-quotes surrounding attribute values).
181
+ #
182
+ # print CGI.escapeElement('<BR><A HREF="url"></A>', "A", "IMG")
183
+ # # "<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt"
184
+ #
185
+ # print CGI.escapeElement('<BR><A HREF="url"></A>', ["A", "IMG"])
186
+ # # "<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt"
187
+ def escapeElement(string, *elements)
188
+ elements = elements[0] if elements[0].kind_of?(Array)
189
+ unless elements.empty?
190
+ string.gsub(/<\/?(?:#{elements.join("|")})\b[^<>]*+>?/im) do
191
+ CGI.escapeHTML($&)
192
+ end
193
+ else
194
+ string
195
+ end
196
+ end
197
+
198
+ # Undo escaping such as that done by CGI.escapeElement()
199
+ #
200
+ # print CGI.unescapeElement(
201
+ # CGI.escapeHTML('<BR><A HREF="url"></A>'), "A", "IMG")
202
+ # # "&lt;BR&gt;<A HREF="url"></A>"
203
+ #
204
+ # print CGI.unescapeElement(
205
+ # CGI.escapeHTML('<BR><A HREF="url"></A>'), ["A", "IMG"])
206
+ # # "&lt;BR&gt;<A HREF="url"></A>"
207
+ def unescapeElement(string, *elements)
208
+ elements = elements[0] if elements[0].kind_of?(Array)
209
+ unless elements.empty?
210
+ string.gsub(/&lt;\/?(?:#{elements.join("|")})\b(?>[^&]+|&(?![gl]t;)\w+;)*(?:&gt;)?/im) do
211
+ unescapeHTML($&)
212
+ end
213
+ else
214
+ string
215
+ end
216
+ end
217
+
218
+ # Synonym for CGI.escapeElement(str)
219
+ alias escape_element escapeElement
220
+
221
+ # Synonym for CGI.unescapeElement(str)
222
+ alias unescape_element unescapeElement
223
+
224
+ end
@@ -11,7 +11,10 @@
11
11
  # cgi/session.rb for more details on session storage managers.
12
12
 
13
13
  require_relative '../session'
14
- require 'pstore'
14
+ begin
15
+ require 'pstore'
16
+ rescue LoadError
17
+ end
15
18
 
16
19
  class CGI
17
20
  class Session
@@ -82,7 +85,7 @@ class CGI
82
85
  File::unlink path
83
86
  end
84
87
 
85
- end
88
+ end if defined?(::PStore)
86
89
  end
87
90
  end
88
91
  # :enddoc:
data/lib/cgi/session.rb CHANGED
@@ -279,7 +279,7 @@ class CGI
279
279
  # fields are surrounded by a <fieldset> tag in HTML 4 generation, which
280
280
  # is _not_ invisible on many browsers; you may wish to disable the
281
281
  # use of fieldsets with code similar to the following
282
- # (see http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/37805)
282
+ # (see https://blade.ruby-lang.org/ruby-list/37805)
283
283
  #
284
284
  # cgi = CGI.new("html4")
285
285
  # class << cgi
data/lib/cgi/util.rb CHANGED
@@ -4,214 +4,8 @@ class CGI
4
4
  include Util
5
5
  extend Util
6
6
  end
7
- module CGI::Util
8
- @@accept_charset = Encoding::UTF_8 unless defined?(@@accept_charset)
9
-
10
- # URL-encode a string into application/x-www-form-urlencoded.
11
- # Space characters (+" "+) are encoded with plus signs (+"+"+)
12
- # url_encoded_string = CGI.escape("'Stop!' said Fred")
13
- # # => "%27Stop%21%27+said+Fred"
14
- def escape(string)
15
- encoding = string.encoding
16
- buffer = string.b
17
- buffer.gsub!(/([^ a-zA-Z0-9_.\-~]+)/) do |m|
18
- '%' + m.unpack('H2' * m.bytesize).join('%').upcase
19
- end
20
- buffer.tr!(' ', '+')
21
- buffer.force_encoding(encoding)
22
- end
23
-
24
- # URL-decode an application/x-www-form-urlencoded string with encoding(optional).
25
- # string = CGI.unescape("%27Stop%21%27+said+Fred")
26
- # # => "'Stop!' said Fred"
27
- def unescape(string, encoding = @@accept_charset)
28
- str = string.tr('+', ' ')
29
- str = str.b
30
- str.gsub!(/((?:%[0-9a-fA-F]{2})+)/) do |m|
31
- [m.delete('%')].pack('H*')
32
- end
33
- str.force_encoding(encoding)
34
- str.valid_encoding? ? str : str.force_encoding(string.encoding)
35
- end
36
-
37
- # URL-encode a string following RFC 3986
38
- # Space characters (+" "+) are encoded with (+"%20"+)
39
- # url_encoded_string = CGI.escape("'Stop!' said Fred")
40
- # # => "%27Stop%21%27%20said%20Fred"
41
- def escapeURIComponent(string)
42
- encoding = string.encoding
43
- buffer = string.b
44
- buffer.gsub!(/([^a-zA-Z0-9_.\-~]+)/) do |m|
45
- '%' + m.unpack('H2' * m.bytesize).join('%').upcase
46
- end
47
- buffer.force_encoding(encoding)
48
- end
49
-
50
- # URL-decode a string following RFC 3986 with encoding(optional).
51
- # string = CGI.unescape("%27Stop%21%27+said%20Fred")
52
- # # => "'Stop!'+said Fred"
53
- def unescapeURIComponent(string, encoding = @@accept_charset)
54
- str = string.b
55
- str.gsub!(/((?:%[0-9a-fA-F]{2})+)/) do |m|
56
- [m.delete('%')].pack('H*')
57
- end
58
- str.force_encoding(encoding)
59
- str.valid_encoding? ? str : str.force_encoding(string.encoding)
60
- end
61
-
62
- # The set of special characters and their escaped values
63
- TABLE_FOR_ESCAPE_HTML__ = {
64
- "'" => '&#39;',
65
- '&' => '&amp;',
66
- '"' => '&quot;',
67
- '<' => '&lt;',
68
- '>' => '&gt;',
69
- }
70
-
71
- # Escape special characters in HTML, namely '&\"<>
72
- # CGI.escapeHTML('Usage: foo "bar" <baz>')
73
- # # => "Usage: foo &quot;bar&quot; &lt;baz&gt;"
74
- def escapeHTML(string)
75
- enc = string.encoding
76
- unless enc.ascii_compatible?
77
- if enc.dummy?
78
- origenc = enc
79
- enc = Encoding::Converter.asciicompat_encoding(enc)
80
- string = enc ? string.encode(enc) : string.b
81
- end
82
- table = Hash[TABLE_FOR_ESCAPE_HTML__.map {|pair|pair.map {|s|s.encode(enc)}}]
83
- string = string.gsub(/#{"['&\"<>]".encode(enc)}/, table)
84
- string.encode!(origenc) if origenc
85
- string
86
- else
87
- string = string.b
88
- string.gsub!(/['&\"<>]/, TABLE_FOR_ESCAPE_HTML__)
89
- string.force_encoding(enc)
90
- end
91
- end
92
-
93
- begin
94
- require 'cgi/escape'
95
- rescue LoadError
96
- end
97
-
98
- # Unescape a string that has been HTML-escaped
99
- # CGI.unescapeHTML("Usage: foo &quot;bar&quot; &lt;baz&gt;")
100
- # # => "Usage: foo \"bar\" <baz>"
101
- def unescapeHTML(string)
102
- enc = string.encoding
103
- unless enc.ascii_compatible?
104
- if enc.dummy?
105
- origenc = enc
106
- enc = Encoding::Converter.asciicompat_encoding(enc)
107
- string = enc ? string.encode(enc) : string.b
108
- end
109
- string = string.gsub(Regexp.new('&(apos|amp|quot|gt|lt|#[0-9]+|#x[0-9A-Fa-f]+);'.encode(enc))) do
110
- case $1.encode(Encoding::US_ASCII)
111
- when 'apos' then "'".encode(enc)
112
- when 'amp' then '&'.encode(enc)
113
- when 'quot' then '"'.encode(enc)
114
- when 'gt' then '>'.encode(enc)
115
- when 'lt' then '<'.encode(enc)
116
- when /\A#0*(\d+)\z/ then $1.to_i.chr(enc)
117
- when /\A#x([0-9a-f]+)\z/i then $1.hex.chr(enc)
118
- end
119
- end
120
- string.encode!(origenc) if origenc
121
- return string
122
- end
123
- return string unless string.include? '&'
124
- charlimit = case enc
125
- when Encoding::UTF_8; 0x10ffff
126
- when Encoding::ISO_8859_1; 256
127
- else 128
128
- end
129
- string = string.b
130
- string.gsub!(/&(apos|amp|quot|gt|lt|\#[0-9]+|\#[xX][0-9A-Fa-f]+);/) do
131
- match = $1.dup
132
- case match
133
- when 'apos' then "'"
134
- when 'amp' then '&'
135
- when 'quot' then '"'
136
- when 'gt' then '>'
137
- when 'lt' then '<'
138
- when /\A#0*(\d+)\z/
139
- n = $1.to_i
140
- if n < charlimit
141
- n.chr(enc)
142
- else
143
- "&##{$1};"
144
- end
145
- when /\A#x([0-9a-f]+)\z/i
146
- n = $1.hex
147
- if n < charlimit
148
- n.chr(enc)
149
- else
150
- "&#x#{$1};"
151
- end
152
- else
153
- "&#{match};"
154
- end
155
- end
156
- string.force_encoding enc
157
- end
158
-
159
- # Synonym for CGI.escapeHTML(str)
160
- alias escape_html escapeHTML
161
-
162
- # Synonym for CGI.unescapeHTML(str)
163
- alias unescape_html unescapeHTML
164
-
165
- # Escape only the tags of certain HTML elements in +string+.
166
- #
167
- # Takes an element or elements or array of elements. Each element
168
- # is specified by the name of the element, without angle brackets.
169
- # This matches both the start and the end tag of that element.
170
- # The attribute list of the open tag will also be escaped (for
171
- # instance, the double-quotes surrounding attribute values).
172
- #
173
- # print CGI.escapeElement('<BR><A HREF="url"></A>', "A", "IMG")
174
- # # "<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt"
175
- #
176
- # print CGI.escapeElement('<BR><A HREF="url"></A>', ["A", "IMG"])
177
- # # "<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt"
178
- def escapeElement(string, *elements)
179
- elements = elements[0] if elements[0].kind_of?(Array)
180
- unless elements.empty?
181
- string.gsub(/<\/?(?:#{elements.join("|")})\b[^<>]*+>?/im) do
182
- CGI.escapeHTML($&)
183
- end
184
- else
185
- string
186
- end
187
- end
188
-
189
- # Undo escaping such as that done by CGI.escapeElement()
190
- #
191
- # print CGI.unescapeElement(
192
- # CGI.escapeHTML('<BR><A HREF="url"></A>'), "A", "IMG")
193
- # # "&lt;BR&gt;<A HREF="url"></A>"
194
- #
195
- # print CGI.unescapeElement(
196
- # CGI.escapeHTML('<BR><A HREF="url"></A>'), ["A", "IMG"])
197
- # # "&lt;BR&gt;<A HREF="url"></A>"
198
- def unescapeElement(string, *elements)
199
- elements = elements[0] if elements[0].kind_of?(Array)
200
- unless elements.empty?
201
- string.gsub(/&lt;\/?(?:#{elements.join("|")})\b(?>[^&]+|&(?![gl]t;)\w+;)*(?:&gt;)?/im) do
202
- unescapeHTML($&)
203
- end
204
- else
205
- string
206
- end
207
- end
208
-
209
- # Synonym for CGI.escapeElement(str)
210
- alias escape_element escapeElement
211
-
212
- # Synonym for CGI.unescapeElement(str)
213
- alias unescape_element unescapeElement
214
7
 
8
+ module CGI::Util
215
9
  # Format a +Time+ object as a String using the format specified by RFC 1123.
216
10
  #
217
11
  # CGI.rfc1123_date(Time.now)
@@ -247,6 +41,7 @@ module CGI::Util
247
41
  end
248
42
  lines.gsub(/^((?:#{Regexp::quote(shift)})*)__(?=<\/?\w)/, '\1')
249
43
  end
250
-
251
- alias h escapeHTML
252
44
  end
45
+
46
+ # For backward compatibility
47
+ require 'cgi/escape' unless defined?(CGI::EscapeExt)
data/lib/cgi.rb CHANGED
@@ -144,7 +144,8 @@
144
144
  #
145
145
  # === Utility HTML escape and other methods like a function.
146
146
  #
147
- # There are some utility tool defined in cgi/util.rb .
147
+ # There are some utility tools defined in cgi/util.rb and cgi/escape.rb.
148
+ # Escape and unescape methods are defined in cgi/escape.rb.
148
149
  # And when include, you can use utility methods like a function.
149
150
  #
150
151
  # == Examples of use
@@ -274,24 +275,25 @@
274
275
  #
275
276
  # === Some utility methods
276
277
  #
277
- # require 'cgi/util'
278
+ # require 'cgi/escape'
278
279
  # CGI.escapeHTML('Usage: foo "bar" <baz>')
279
280
  #
280
281
  #
281
282
  # === Some utility methods like a function
282
283
  #
283
- # require 'cgi/util'
284
- # include CGI::Util
284
+ # require 'cgi/escape'
285
+ # include CGI::Escape
285
286
  # escapeHTML('Usage: foo "bar" <baz>')
286
287
  # h('Usage: foo "bar" <baz>') # alias
287
288
  #
288
289
  #
289
290
 
290
291
  class CGI
291
- VERSION = "0.3.7"
292
+ VERSION = "0.5.0"
292
293
  end
293
294
 
295
+ require 'cgi/util'
296
+ require 'cgi/escape' unless defined?(CGI::EscapeExt)
294
297
  require 'cgi/core'
295
298
  require 'cgi/cookie'
296
- require 'cgi/util'
297
299
  CGI.autoload(:HtmlExtension, 'cgi/html')
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cgi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.7
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yukihiro Matsumoto
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-02-26 00:00:00.000000000 Z
10
+ date: 2025-06-04 00:00:00.000000000 Z
12
11
  dependencies: []
13
12
  description: Support for the Common Gateway Interface protocol.
14
13
  email:
@@ -18,7 +17,8 @@ extensions:
18
17
  - ext/cgi/escape/extconf.rb
19
18
  extra_rdoc_files: []
20
19
  files:
21
- - LICENSE.txt
20
+ - BSDL
21
+ - COPYING
22
22
  - README.md
23
23
  - ext/cgi/escape/depend
24
24
  - ext/cgi/escape/escape.c
@@ -26,6 +26,7 @@ files:
26
26
  - lib/cgi.rb
27
27
  - lib/cgi/cookie.rb
28
28
  - lib/cgi/core.rb
29
+ - lib/cgi/escape.rb
29
30
  - lib/cgi/html.rb
30
31
  - lib/cgi/session.rb
31
32
  - lib/cgi/session/pstore.rb
@@ -37,7 +38,6 @@ licenses:
37
38
  metadata:
38
39
  homepage_uri: https://github.com/ruby/cgi
39
40
  source_code_uri: https://github.com/ruby/cgi
40
- post_install_message:
41
41
  rdoc_options: []
42
42
  require_paths:
43
43
  - lib
@@ -52,8 +52,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
52
52
  - !ruby/object:Gem::Version
53
53
  version: '0'
54
54
  requirements: []
55
- rubygems_version: 3.5.11
56
- signing_key:
55
+ rubygems_version: 3.6.7
57
56
  specification_version: 4
58
57
  summary: Support for the Common Gateway Interface protocol.
59
58
  test_files: []