cgi 0.1.0 → 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cdab469fad9274c1f62d5a4a7d4ffd445bdfb0b596b2abd66e098dffd9e48aab
4
- data.tar.gz: 696d10e4d2ecc54f882d190478cac27c5a5b1e879c14eacc0e2ce86b2e00f08a
3
+ metadata.gz: ef7c6fbc3fed4edb75963f96b0b7a150dca2d296730f28eb42844e7582f73ddb
4
+ data.tar.gz: 6dff4891d8e6b75480346969bef5efd4e33c323a8e6dbe2196e07abf5d4b4366
5
5
  SHA512:
6
- metadata.gz: edcf932436436eeb2367704011aad3c31220491278bfd6ca06e358799d18b3548fd73cb3714ca84f2cede0aed6d4161b5072c287db98f960ada0c3c96b0247d7
7
- data.tar.gz: 96eee5f302ebed6ce10b262b394474d3e96712ae7f6ebc5699cb6c17485d0685aa598aaf9fdbce9b6f46df1360bf4ecb9277d082f1c4a858dd884b6aee5852a9
6
+ metadata.gz: 4b6abc351ceaf68ededa9d590fdd7adfb1fe8b32d4818128be7fb10867788cf32de65ea5d11cd4d7a38dc1a4adf19c1faee1b6a3689aeccea943178d18b09f8d
7
+ data.tar.gz: 1d805aede830aabc0c7d7ca577d8bd2bca541956d37cadeda9262a5e5ee01af5d940d4e135b907deadc16d20ef5a8357b2d4bb8817fc4241491f8305030e3d2e
@@ -1,17 +1,2 @@
1
- # AUTOGENERATED DEPENDENCIES START
2
1
  escape.o: $(RUBY_EXTCONF_H)
3
- escape.o: $(arch_hdrdir)/ruby/config.h
4
- escape.o: $(hdrdir)/ruby.h
5
- escape.o: $(hdrdir)/ruby/assert.h
6
- escape.o: $(hdrdir)/ruby/backward.h
7
- escape.o: $(hdrdir)/ruby/defines.h
8
- escape.o: $(hdrdir)/ruby/encoding.h
9
- escape.o: $(hdrdir)/ruby/intern.h
10
- escape.o: $(hdrdir)/ruby/missing.h
11
- escape.o: $(hdrdir)/ruby/onigmo.h
12
- escape.o: $(hdrdir)/ruby/oniguruma.h
13
- escape.o: $(hdrdir)/ruby/ruby.h
14
- escape.o: $(hdrdir)/ruby/st.h
15
- escape.o: $(hdrdir)/ruby/subst.h
16
2
  escape.o: escape.c
17
- # AUTOGENERATED DEPENDENCIES END
@@ -30,15 +30,23 @@ static inline void
30
30
  preserve_original_state(VALUE orig, VALUE dest)
31
31
  {
32
32
  rb_enc_associate(dest, rb_enc_get(orig));
33
+ }
33
34
 
34
- RB_OBJ_INFECT_RAW(dest, orig);
35
+ static inline long
36
+ escaped_length(VALUE str)
37
+ {
38
+ const long len = RSTRING_LEN(str);
39
+ if (len >= LONG_MAX / HTML_ESCAPE_MAX_LEN) {
40
+ ruby_malloc_size_overflow(len, HTML_ESCAPE_MAX_LEN);
41
+ }
42
+ return len * HTML_ESCAPE_MAX_LEN;
35
43
  }
36
44
 
37
45
  static VALUE
38
46
  optimized_escape_html(VALUE str)
39
47
  {
40
48
  VALUE vbuf;
41
- char *buf = ALLOCV_N(char, vbuf, RSTRING_LEN(str) * HTML_ESCAPE_MAX_LEN);
49
+ char *buf = ALLOCV_N(char, vbuf, escaped_length(str));
42
50
  const char *cstr = RSTRING_PTR(str);
43
51
  const char *end = cstr + RSTRING_LEN(str);
44
52
 
@@ -73,8 +81,8 @@ optimized_unescape_html(VALUE str)
73
81
  enum {UNICODE_MAX = 0x10ffff};
74
82
  rb_encoding *enc = rb_enc_get(str);
75
83
  unsigned long charlimit = (strcasecmp(rb_enc_name(enc), "UTF-8") == 0 ? UNICODE_MAX :
76
- strcasecmp(rb_enc_name(enc), "ISO-8859-1") == 0 ? 256 :
77
- 128);
84
+ strcasecmp(rb_enc_name(enc), "ISO-8859-1") == 0 ? 256 :
85
+ 128);
78
86
  long i, len, beg = 0;
79
87
  size_t clen, plen;
80
88
  int overflow;
@@ -86,89 +94,89 @@ optimized_unescape_html(VALUE str)
86
94
  cstr = RSTRING_PTR(str);
87
95
 
88
96
  for (i = 0; i < len; i++) {
89
- unsigned long cc;
90
- char c = cstr[i];
91
- if (c != '&') continue;
92
- plen = i - beg;
93
- if (++i >= len) break;
94
- c = (unsigned char)cstr[i];
97
+ unsigned long cc;
98
+ char c = cstr[i];
99
+ if (c != '&') continue;
100
+ plen = i - beg;
101
+ if (++i >= len) break;
102
+ c = (unsigned char)cstr[i];
95
103
  #define MATCH(s) (len - i >= (int)rb_strlen_lit(s) && \
96
- memcmp(&cstr[i], s, rb_strlen_lit(s)) == 0 && \
97
- (i += rb_strlen_lit(s) - 1, 1))
98
- switch (c) {
99
- case 'a':
100
- ++i;
101
- if (MATCH("pos;")) {
102
- c = '\'';
103
- }
104
- else if (MATCH("mp;")) {
105
- c = '&';
106
- }
107
- else continue;
108
- break;
109
- case 'q':
110
- ++i;
111
- if (MATCH("uot;")) {
112
- c = '"';
113
- }
114
- else continue;
115
- break;
116
- case 'g':
117
- ++i;
118
- if (MATCH("t;")) {
119
- c = '>';
120
- }
121
- else continue;
122
- break;
123
- case 'l':
124
- ++i;
125
- if (MATCH("t;")) {
126
- c = '<';
127
- }
128
- else continue;
129
- break;
130
- case '#':
131
- if (len - ++i >= 2 && ISDIGIT(cstr[i])) {
132
- cc = ruby_scan_digits(&cstr[i], len-i, 10, &clen, &overflow);
133
- }
134
- else if ((cstr[i] == 'x' || cstr[i] == 'X') && len - ++i >= 2 && ISXDIGIT(cstr[i])) {
135
- cc = ruby_scan_digits(&cstr[i], len-i, 16, &clen, &overflow);
136
- }
137
- else continue;
138
- i += clen;
139
- if (overflow || cc >= charlimit || cstr[i] != ';') continue;
140
- if (!dest) {
141
- dest = rb_str_buf_new(len);
142
- }
143
- rb_str_cat(dest, cstr + beg, plen);
144
- if (charlimit > 256) {
145
- rb_str_cat(dest, buf, rb_enc_mbcput((OnigCodePoint)cc, buf, enc));
146
- }
147
- else {
148
- c = (unsigned char)cc;
149
- rb_str_cat(dest, &c, 1);
150
- }
151
- beg = i + 1;
152
- continue;
153
- default:
154
- --i;
155
- continue;
156
- }
157
- if (!dest) {
158
- dest = rb_str_buf_new(len);
159
- }
160
- rb_str_cat(dest, cstr + beg, plen);
161
- rb_str_cat(dest, &c, 1);
162
- beg = i + 1;
104
+ memcmp(&cstr[i], s, rb_strlen_lit(s)) == 0 && \
105
+ (i += rb_strlen_lit(s) - 1, 1))
106
+ switch (c) {
107
+ case 'a':
108
+ ++i;
109
+ if (MATCH("pos;")) {
110
+ c = '\'';
111
+ }
112
+ else if (MATCH("mp;")) {
113
+ c = '&';
114
+ }
115
+ else continue;
116
+ break;
117
+ case 'q':
118
+ ++i;
119
+ if (MATCH("uot;")) {
120
+ c = '"';
121
+ }
122
+ else continue;
123
+ break;
124
+ case 'g':
125
+ ++i;
126
+ if (MATCH("t;")) {
127
+ c = '>';
128
+ }
129
+ else continue;
130
+ break;
131
+ case 'l':
132
+ ++i;
133
+ if (MATCH("t;")) {
134
+ c = '<';
135
+ }
136
+ else continue;
137
+ break;
138
+ case '#':
139
+ if (len - ++i >= 2 && ISDIGIT(cstr[i])) {
140
+ cc = ruby_scan_digits(&cstr[i], len-i, 10, &clen, &overflow);
141
+ }
142
+ else if ((cstr[i] == 'x' || cstr[i] == 'X') && len - ++i >= 2 && ISXDIGIT(cstr[i])) {
143
+ cc = ruby_scan_digits(&cstr[i], len-i, 16, &clen, &overflow);
144
+ }
145
+ else continue;
146
+ i += clen;
147
+ if (overflow || cc >= charlimit || cstr[i] != ';') continue;
148
+ if (!dest) {
149
+ dest = rb_str_buf_new(len);
150
+ }
151
+ rb_str_cat(dest, cstr + beg, plen);
152
+ if (charlimit > 256) {
153
+ rb_str_cat(dest, buf, rb_enc_mbcput((OnigCodePoint)cc, buf, enc));
154
+ }
155
+ else {
156
+ c = (unsigned char)cc;
157
+ rb_str_cat(dest, &c, 1);
158
+ }
159
+ beg = i + 1;
160
+ continue;
161
+ default:
162
+ --i;
163
+ continue;
164
+ }
165
+ if (!dest) {
166
+ dest = rb_str_buf_new(len);
167
+ }
168
+ rb_str_cat(dest, cstr + beg, plen);
169
+ rb_str_cat(dest, &c, 1);
170
+ beg = i + 1;
163
171
  }
164
172
 
165
173
  if (dest) {
166
- rb_str_cat(dest, cstr + beg, len - beg);
167
- preserve_original_state(str, dest);
168
- return dest;
174
+ rb_str_cat(dest, cstr + beg, len - beg);
175
+ preserve_original_state(str, dest);
176
+ return dest;
169
177
  }
170
178
  else {
171
- return rb_str_dup(str);
179
+ return rb_str_dup(str);
172
180
  }
173
181
  }
174
182
 
@@ -192,7 +200,7 @@ url_unreserved_char(unsigned char c)
192
200
  }
193
201
 
194
202
  static VALUE
195
- optimized_escape(VALUE str)
203
+ optimized_escape(VALUE str, int plus_escape)
196
204
  {
197
205
  long i, len, beg = 0;
198
206
  VALUE dest = 0;
@@ -203,38 +211,38 @@ optimized_escape(VALUE str)
203
211
  cstr = RSTRING_PTR(str);
204
212
 
205
213
  for (i = 0; i < len; ++i) {
206
- const unsigned char c = (unsigned char)cstr[i];
207
- if (!url_unreserved_char(c)) {
208
- if (!dest) {
209
- dest = rb_str_buf_new(len);
210
- }
211
-
212
- rb_str_cat(dest, cstr + beg, i - beg);
213
- beg = i + 1;
214
-
215
- if (c == ' ') {
216
- rb_str_cat_cstr(dest, "+");
217
- }
218
- else {
219
- buf[1] = upper_hexdigits[(c >> 4) & 0xf];
220
- buf[2] = upper_hexdigits[c & 0xf];
221
- rb_str_cat(dest, buf, 3);
222
- }
223
- }
214
+ const unsigned char c = (unsigned char)cstr[i];
215
+ if (!url_unreserved_char(c)) {
216
+ if (!dest) {
217
+ dest = rb_str_buf_new(len);
218
+ }
219
+
220
+ rb_str_cat(dest, cstr + beg, i - beg);
221
+ beg = i + 1;
222
+
223
+ if (plus_escape && c == ' ') {
224
+ rb_str_cat_cstr(dest, "+");
225
+ }
226
+ else {
227
+ buf[1] = upper_hexdigits[(c >> 4) & 0xf];
228
+ buf[2] = upper_hexdigits[c & 0xf];
229
+ rb_str_cat(dest, buf, 3);
230
+ }
231
+ }
224
232
  }
225
233
 
226
234
  if (dest) {
227
- rb_str_cat(dest, cstr + beg, len - beg);
228
- preserve_original_state(str, dest);
229
- return dest;
235
+ rb_str_cat(dest, cstr + beg, len - beg);
236
+ preserve_original_state(str, dest);
237
+ return dest;
230
238
  }
231
239
  else {
232
- return rb_str_dup(str);
240
+ return rb_str_dup(str);
233
241
  }
234
242
  }
235
243
 
236
244
  static VALUE
237
- optimized_unescape(VALUE str, VALUE encoding)
245
+ optimized_unescape(VALUE str, VALUE encoding, int unescape_plus)
238
246
  {
239
247
  long i, len, beg = 0;
240
248
  VALUE dest = 0;
@@ -246,52 +254,52 @@ optimized_unescape(VALUE str, VALUE encoding)
246
254
  cstr = RSTRING_PTR(str);
247
255
 
248
256
  for (i = 0; i < len; ++i) {
249
- char buf[1];
250
- const char c = cstr[i];
251
- int clen = 0;
252
- if (c == '%') {
253
- if (i + 3 > len) break;
254
- if (!ISXDIGIT(cstr[i+1])) continue;
255
- if (!ISXDIGIT(cstr[i+2])) continue;
256
- buf[0] = ((char_to_number(cstr[i+1]) << 4)
257
- | char_to_number(cstr[i+2]));
258
- clen = 2;
259
- }
260
- else if (c == '+') {
261
- buf[0] = ' ';
262
- }
263
- else {
264
- continue;
265
- }
266
-
267
- if (!dest) {
268
- dest = rb_str_buf_new(len);
269
- }
270
-
271
- rb_str_cat(dest, cstr + beg, i - beg);
272
- i += clen;
273
- beg = i + 1;
274
-
275
- rb_str_cat(dest, buf, 1);
257
+ char buf[1];
258
+ const char c = cstr[i];
259
+ int clen = 0;
260
+ if (c == '%') {
261
+ if (i + 3 > len) break;
262
+ if (!ISXDIGIT(cstr[i+1])) continue;
263
+ if (!ISXDIGIT(cstr[i+2])) continue;
264
+ buf[0] = ((char_to_number(cstr[i+1]) << 4)
265
+ | char_to_number(cstr[i+2]));
266
+ clen = 2;
267
+ }
268
+ else if (unescape_plus && c == '+') {
269
+ buf[0] = ' ';
270
+ }
271
+ else {
272
+ continue;
273
+ }
274
+
275
+ if (!dest) {
276
+ dest = rb_str_buf_new(len);
277
+ }
278
+
279
+ rb_str_cat(dest, cstr + beg, i - beg);
280
+ i += clen;
281
+ beg = i + 1;
282
+
283
+ rb_str_cat(dest, buf, 1);
276
284
  }
277
285
 
278
286
  if (dest) {
279
- rb_str_cat(dest, cstr + beg, len - beg);
280
- preserve_original_state(str, dest);
281
- cr = ENC_CODERANGE_UNKNOWN;
287
+ rb_str_cat(dest, cstr + beg, len - beg);
288
+ preserve_original_state(str, dest);
289
+ cr = ENC_CODERANGE_UNKNOWN;
282
290
  }
283
291
  else {
284
- dest = rb_str_dup(str);
285
- cr = ENC_CODERANGE(str);
292
+ dest = rb_str_dup(str);
293
+ cr = ENC_CODERANGE(str);
286
294
  }
287
295
  origenc = rb_enc_get_index(str);
288
296
  if (origenc != encidx) {
289
- rb_enc_associate_index(dest, encidx);
290
- if (!ENC_CODERANGE_CLEAN_P(rb_enc_str_coderange(dest))) {
291
- rb_enc_associate_index(dest, origenc);
292
- if (cr != ENC_CODERANGE_UNKNOWN)
293
- ENC_CODERANGE_SET(dest, cr);
294
- }
297
+ rb_enc_associate_index(dest, encidx);
298
+ if (!ENC_CODERANGE_CLEAN_P(rb_enc_str_coderange(dest))) {
299
+ rb_enc_associate_index(dest, origenc);
300
+ if (cr != ENC_CODERANGE_UNKNOWN)
301
+ ENC_CODERANGE_SET(dest, cr);
302
+ }
295
303
  }
296
304
  return dest;
297
305
  }
@@ -309,10 +317,10 @@ cgiesc_escape_html(VALUE self, VALUE str)
309
317
  StringValue(str);
310
318
 
311
319
  if (rb_enc_str_asciicompat_p(str)) {
312
- return optimized_escape_html(str);
320
+ return optimized_escape_html(str);
313
321
  }
314
322
  else {
315
- return rb_call_super(1, &str);
323
+ return rb_call_super(1, &str);
316
324
  }
317
325
  }
318
326
 
@@ -329,10 +337,10 @@ cgiesc_unescape_html(VALUE self, VALUE str)
329
337
  StringValue(str);
330
338
 
331
339
  if (rb_enc_str_asciicompat_p(str)) {
332
- return optimized_unescape_html(str);
340
+ return optimized_unescape_html(str);
333
341
  }
334
342
  else {
335
- return rb_call_super(1, &str);
343
+ return rb_call_super(1, &str);
336
344
  }
337
345
  }
338
346
 
@@ -340,7 +348,7 @@ cgiesc_unescape_html(VALUE self, VALUE str)
340
348
  * call-seq:
341
349
  * CGI.escape(string) -> string
342
350
  *
343
- * Returns URL-escaped string.
351
+ * Returns URL-escaped string (+application/x-www-form-urlencoded+).
344
352
  *
345
353
  */
346
354
  static VALUE
@@ -349,10 +357,10 @@ cgiesc_escape(VALUE self, VALUE str)
349
357
  StringValue(str);
350
358
 
351
359
  if (rb_enc_str_asciicompat_p(str)) {
352
- return optimized_escape(str);
360
+ return optimized_escape(str, 1);
353
361
  }
354
362
  else {
355
- return rb_call_super(1, &str);
363
+ return rb_call_super(1, &str);
356
364
  }
357
365
  }
358
366
 
@@ -360,7 +368,7 @@ static VALUE
360
368
  accept_charset(int argc, VALUE *argv, VALUE self)
361
369
  {
362
370
  if (argc > 0)
363
- return argv[0];
371
+ return argv[0];
364
372
  return rb_cvar_get(CLASS_OF(self), id_accept_charset);
365
373
  }
366
374
 
@@ -368,7 +376,7 @@ accept_charset(int argc, VALUE *argv, VALUE self)
368
376
  * call-seq:
369
377
  * CGI.unescape(string, encoding=@@accept_charset) -> string
370
378
  *
371
- * Returns URL-unescaped string.
379
+ * Returns URL-unescaped string (+application/x-www-form-urlencoded+).
372
380
  *
373
381
  */
374
382
  static VALUE
@@ -379,17 +387,64 @@ cgiesc_unescape(int argc, VALUE *argv, VALUE self)
379
387
  StringValue(str);
380
388
 
381
389
  if (rb_enc_str_asciicompat_p(str)) {
382
- VALUE enc = accept_charset(argc-1, argv+1, self);
383
- return optimized_unescape(str, enc);
390
+ VALUE enc = accept_charset(argc-1, argv+1, self);
391
+ return optimized_unescape(str, enc, 1);
392
+ }
393
+ else {
394
+ return rb_call_super(argc, argv);
395
+ }
396
+ }
397
+
398
+ /*
399
+ * call-seq:
400
+ * CGI.escapeURIComponent(string) -> string
401
+ *
402
+ * Returns URL-escaped string following RFC 3986.
403
+ *
404
+ */
405
+ static VALUE
406
+ cgiesc_escape_uri_component(VALUE self, VALUE str)
407
+ {
408
+ StringValue(str);
409
+
410
+ if (rb_enc_str_asciicompat_p(str)) {
411
+ return optimized_escape(str, 0);
412
+ }
413
+ else {
414
+ return rb_call_super(1, &str);
415
+ }
416
+ }
417
+
418
+ /*
419
+ * call-seq:
420
+ * CGI.unescapeURIComponent(string, encoding=@@accept_charset) -> string
421
+ *
422
+ * Returns URL-unescaped string following RFC 3986.
423
+ *
424
+ */
425
+ static VALUE
426
+ cgiesc_unescape_uri_component(int argc, VALUE *argv, VALUE self)
427
+ {
428
+ VALUE str = (rb_check_arity(argc, 1, 2), argv[0]);
429
+
430
+ StringValue(str);
431
+
432
+ if (rb_enc_str_asciicompat_p(str)) {
433
+ VALUE enc = accept_charset(argc-1, argv+1, self);
434
+ return optimized_unescape(str, enc, 0);
384
435
  }
385
436
  else {
386
- return rb_call_super(argc, argv);
437
+ return rb_call_super(argc, argv);
387
438
  }
388
439
  }
389
440
 
390
441
  void
391
442
  Init_escape(void)
392
443
  {
444
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
445
+ rb_ext_ractor_safe(true);
446
+ #endif
447
+
393
448
  id_accept_charset = rb_intern_const("@@accept_charset");
394
449
  InitVM(escape);
395
450
  }
@@ -402,6 +457,8 @@ InitVM_escape(void)
402
457
  rb_mUtil = rb_define_module_under(rb_cCGI, "Util");
403
458
  rb_define_method(rb_mEscape, "escapeHTML", cgiesc_escape_html, 1);
404
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);
405
462
  rb_define_method(rb_mEscape, "escape", cgiesc_escape, 1);
406
463
  rb_define_method(rb_mEscape, "unescape", cgiesc_unescape, -1);
407
464
  rb_prepend_module(rb_mUtil, rb_mEscape);
data/lib/cgi/cookie.rb CHANGED
@@ -40,6 +40,10 @@ class CGI
40
40
  class Cookie < Array
41
41
  @@accept_charset="UTF-8" unless defined?(@@accept_charset)
42
42
 
43
+ TOKEN_RE = %r"\A[[!-~]&&[^()<>@,;:\\\"/?=\[\]{}]]+\z"
44
+ PATH_VALUE_RE = %r"\A[[ -~]&&[^;]]*\z"
45
+ DOMAIN_VALUE_RE = %r"\A\.?(?<label>(?!-)[-A-Za-z0-9]+(?<!-))(?:\.\g<label>)*\z"
46
+
43
47
  # Create a new CGI::Cookie object.
44
48
  #
45
49
  # :call-seq:
@@ -57,7 +61,7 @@ class CGI
57
61
  #
58
62
  # name:: the name of the cookie. Required.
59
63
  # value:: the cookie's value or list of values.
60
- # path:: the path for which this cookie applies. Defaults to the
64
+ # path:: the path for which this cookie applies. Defaults to
61
65
  # the value of the +SCRIPT_NAME+ environment variable.
62
66
  # domain:: the domain for which this cookie applies.
63
67
  # expires:: the time at which this cookie expires, as a +Time+ object.
@@ -72,9 +76,8 @@ class CGI
72
76
  @domain = nil
73
77
  @expires = nil
74
78
  if name.kind_of?(String)
75
- @name = name
76
- %r|^(.*/)|.match(ENV["SCRIPT_NAME"])
77
- @path = ($1 or "")
79
+ self.name = name
80
+ self.path = (%r|\A(.*/)| =~ ENV["SCRIPT_NAME"] ? $1 : "")
78
81
  @secure = false
79
82
  @httponly = false
80
83
  return super(value)
@@ -85,16 +88,11 @@ class CGI
85
88
  raise ArgumentError, "`name' required"
86
89
  end
87
90
 
88
- @name = options["name"]
91
+ self.name = options["name"]
89
92
  value = Array(options["value"])
90
93
  # simple support for IE
91
- if options["path"]
92
- @path = options["path"]
93
- else
94
- %r|^(.*/)|.match(ENV["SCRIPT_NAME"])
95
- @path = ($1 or "")
96
- end
97
- @domain = options["domain"]
94
+ self.path = options["path"] || (%r|\A(.*/)| =~ ENV["SCRIPT_NAME"] ? $1 : "")
95
+ self.domain = options["domain"]
98
96
  @expires = options["expires"]
99
97
  @secure = options["secure"] == true
100
98
  @httponly = options["httponly"] == true
@@ -103,11 +101,35 @@ class CGI
103
101
  end
104
102
 
105
103
  # Name of this cookie, as a +String+
106
- attr_accessor :name
104
+ attr_reader :name
105
+ # Set name of this cookie
106
+ def name=(str)
107
+ if str and !TOKEN_RE.match?(str)
108
+ raise ArgumentError, "invalid name: #{str.dump}"
109
+ end
110
+ @name = str
111
+ end
112
+
107
113
  # Path for which this cookie applies, as a +String+
108
- attr_accessor :path
114
+ attr_reader :path
115
+ # Set path for which this cookie applies
116
+ def path=(str)
117
+ if str and !PATH_VALUE_RE.match?(str)
118
+ raise ArgumentError, "invalid path: #{str.dump}"
119
+ end
120
+ @path = str
121
+ end
122
+
109
123
  # Domain for which this cookie applies, as a +String+
110
- attr_accessor :domain
124
+ attr_reader :domain
125
+ # Set domain for which this cookie applies
126
+ def domain=(str)
127
+ if str and ((str = str.b).bytesize > 255 or !DOMAIN_VALUE_RE.match?(str))
128
+ raise ArgumentError, "invalid domain: #{str.dump}"
129
+ end
130
+ @domain = str
131
+ end
132
+
111
133
  # Time at which this cookie expires, as a +Time+
112
134
  attr_accessor :expires
113
135
  # True if this cookie is secure; false otherwise
@@ -146,7 +168,7 @@ class CGI
146
168
  buf = "#{@name}=#{val}".dup
147
169
  buf << "; domain=#{@domain}" if @domain
148
170
  buf << "; path=#{@path}" if @path
149
- buf << "; expires=#{CGI::rfc1123_date(@expires)}" if @expires
171
+ buf << "; expires=#{CGI.rfc1123_date(@expires)}" if @expires
150
172
  buf << "; secure" if @secure
151
173
  buf << "; HttpOnly" if @httponly
152
174
  buf
@@ -165,7 +187,6 @@ class CGI
165
187
  raw_cookie.split(/;\s?/).each do |pairs|
166
188
  name, values = pairs.split('=',2)
167
189
  next unless name and values
168
- name = CGI.unescape(name)
169
190
  values ||= ""
170
191
  values = values.split('&').collect{|v| CGI.unescape(v,@@accept_charset) }
171
192
  if cookies.has_key?(name)