http-cookie 1.0.2 → 1.0.5

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
- SHA1:
3
- metadata.gz: 633adcbc5625bcf9d8c1509b9480d955f3107a06
4
- data.tar.gz: 17c8fefbe45bb8429d3c533a1338bf4cec02345e
2
+ SHA256:
3
+ metadata.gz: 5230b0bd44e032652855e7b9e60e3d994ca56adbd57550c7520930d4dbf734a4
4
+ data.tar.gz: 65240197f49ac57bac8c6f3d1104cfe4f8fff77e1ac992c05c72d74efbba8300
5
5
  SHA512:
6
- metadata.gz: 190e3fc5a0a658b73a9fc6c0e43937b6fd9fdebb9b6d92e09edd51c24209fbd2fb61e9ea49eb29621f2fefeb1ec5095779deded65c343f2f0c52c4f53c1e0b76
7
- data.tar.gz: 96627fd5e6617b71c0b5dadf08e918169aabeda0c9ebf0f3a3d1d3d4c920b3999637f61009f4d531ddb588178bd6f0e26529b9ee49bf1808374971b7337a69f3
6
+ metadata.gz: 7fc5bb2e287d60d060c54eb9fb9ccb6d55c55e84ec35525deff8c088c873d6ac26db86f7f1cf3c03a7cbf05e397b6cd0e3a1e1171c2dcff8848e0345a34b0905
7
+ data.tar.gz: 1c85e07a65fac1d5440126bea27dbc01160edc9a791f56e021cd3142070eada54bf1ec3cda31c9d9273f23c3a84c8786c308bcdd27e03f7266c203dde4abdd6f
@@ -0,0 +1,37 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ pull_request:
8
+ branches:
9
+ - "*"
10
+
11
+ jobs:
12
+ test:
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ os: [ubuntu]
17
+ # We still kind of support Ruby 1.8.7
18
+ ruby: [2.7, "3.0", 3.1, head, jruby]
19
+
20
+ name: >-
21
+ ${{matrix.os}}:ruby-${{matrix.ruby}}
22
+ runs-on: ${{matrix.os}}-latest
23
+ continue-on-error: ${{matrix.ruby == 'head' || matrix.ruby == 'jruby'}}
24
+
25
+ steps:
26
+ - name: Check out
27
+ uses: actions/checkout@v2
28
+
29
+ - name: Set up ruby and bundle
30
+ uses: ruby/setup-ruby@v1
31
+ with:
32
+ ruby-version: ${{matrix.ruby}}
33
+ bundler-cache: true
34
+
35
+ - name: Run rake
36
+ run: |
37
+ bundle exec rake
data/CHANGELOG.md CHANGED
@@ -1,3 +1,20 @@
1
+ ## 1.0.5 (2022-05-25)
2
+
3
+ - Silence SQLite3 warnings
4
+
5
+ ## 1.0.4 (2021-06-07)
6
+
7
+ - Support Mozilla's cookie storage format up to version 7.
8
+
9
+ - Fix the time representation with creationTime and lastAccessed in
10
+ MozillaStore. (#8)
11
+
12
+ ## 1.0.3 (2016-09-30)
13
+
14
+ - Treat comma as normal character in HTTP::Cookie.cookie_value_to_hash
15
+ instead of key-value pair separator. This should fix the problem
16
+ described in CVE-2016-7401.
17
+
1
18
  ## 1.0.2 (2013-09-10)
2
19
 
3
20
  - Fix HTTP::Cookie.parse so that it does not raise ArgumentError
data/http-cookie.gemspec CHANGED
@@ -25,10 +25,11 @@ Gem::Specification.new do |gem|
25
25
  gem.extra_rdoc_files = ['README.md', 'LICENSE.txt']
26
26
 
27
27
  gem.add_runtime_dependency("domain_name", ["~> 0.5"])
28
- gem.add_development_dependency("sqlite3", ["~> 1.3.3"]) unless defined?(JRUBY_VERSION)
28
+ gem.add_development_dependency("sqlite3", ["~> 1.3"]) unless defined?(JRUBY_VERSION)
29
29
  gem.add_development_dependency("bundler", [">= 1.2.0"])
30
- gem.add_development_dependency("test-unit", [">= 2.4.3"])
31
- gem.add_development_dependency("rake", [">= 0.9.2.2"])
32
- gem.add_development_dependency("rdoc", ["> 2.4.2"])
30
+ gem.add_development_dependency("test-unit", [">= 2.4.3", *("< 3" if RUBY_VERSION < "1.9")])
31
+ gem.add_development_dependency("rake", [">= 0.9.2.2", *("< 11" if RUBY_VERSION < "1.9")])
32
+ gem.add_development_dependency("rdoc", RUBY_VERSION > "1.9" ? "> 2.4.2" : "~> 2.4.2")
33
33
  gem.add_development_dependency("simplecov", [">= 0"])
34
+ gem.add_development_dependency("json", ["< 2"]) if RUBY_VERSION < "2.0"
34
35
  end
@@ -50,7 +50,7 @@ class HTTP::Cookie::Scanner < StringScanner
50
50
  }
51
51
  end
52
52
 
53
- def scan_value
53
+ def scan_value(comma_as_separator = false)
54
54
  ''.tap { |s|
55
55
  case
56
56
  when scan(/[^,;"]+/)
@@ -59,7 +59,9 @@ class HTTP::Cookie::Scanner < StringScanner
59
59
  # RFC 6265 2.2
60
60
  # A cookie-value may be DQUOTE'd.
61
61
  s << scan_dquoted
62
- when check(/;|#{RE_COOKIE_COMMA}/o)
62
+ when check(/;/)
63
+ break
64
+ when comma_as_separator && check(RE_COOKIE_COMMA)
63
65
  break
64
66
  else
65
67
  s << getch
@@ -68,12 +70,12 @@ class HTTP::Cookie::Scanner < StringScanner
68
70
  }
69
71
  end
70
72
 
71
- def scan_name_value
73
+ def scan_name_value(comma_as_separator = false)
72
74
  name = scan_name
73
75
  if skip(/\=/)
74
- value = scan_value
76
+ value = scan_value(comma_as_separator)
75
77
  else
76
- scan_value
78
+ scan_value(comma_as_separator)
77
79
  value = nil
78
80
  end
79
81
  [name, value]
@@ -159,7 +161,7 @@ class HTTP::Cookie::Scanner < StringScanner
159
161
 
160
162
  skip_wsp
161
163
 
162
- name, value = scan_name_value
164
+ name, value = scan_name_value(true)
163
165
  if value.nil?
164
166
  @logger.warn("Cookie definition lacks a name-value pair.") if @logger
165
167
  elsif name.empty?
@@ -176,7 +178,7 @@ class HTTP::Cookie::Scanner < StringScanner
176
178
  break
177
179
  when skip(/;/)
178
180
  skip_wsp
179
- aname, avalue = scan_name_value
181
+ aname, avalue = scan_name_value(true)
180
182
  next if aname.empty? || value.nil?
181
183
  aname.downcase!
182
184
  case aname
@@ -218,13 +220,12 @@ class HTTP::Cookie::Scanner < StringScanner
218
220
  until eos?
219
221
  skip_wsp
220
222
 
221
- name, value = scan_name_value
223
+ # Do not treat comma in a Cookie header value as separator; see CVE-2016-7401
224
+ name, value = scan_name_value(false)
222
225
 
223
226
  yield name, value if value
224
227
 
225
- # The comma is used as separator for concatenating multiple
226
- # values of a header.
227
- skip(/[;,]/)
228
+ skip(/;/)
228
229
  end
229
230
  end
230
231
  end
@@ -1,5 +1,5 @@
1
1
  module HTTP
2
2
  class Cookie
3
- VERSION = "1.0.2"
3
+ VERSION = "1.0.5"
4
4
  end
5
5
  end
data/lib/http/cookie.rb CHANGED
@@ -128,7 +128,7 @@ class HTTP::Cookie
128
128
  # new("name" => "uid", "value" => "a12345", "Domain" => 'www.example.org')
129
129
  #
130
130
  def initialize(*args)
131
- @origin = @domain = @path =
131
+ @name = @origin = @domain = @path =
132
132
  @expires = @max_age = nil
133
133
  @for_domain = @secure = @httponly = false
134
134
  @session = true
@@ -17,8 +17,8 @@ class HTTP::CookieJar::AbstractStore
17
17
  begin
18
18
  require 'http/cookie_jar/%s_store' % symbol
19
19
  @@class_map.fetch(symbol)
20
- rescue LoadError, IndexError
21
- raise IndexError, 'cookie store unavailable: %s' % symbol.inspect
20
+ rescue LoadError, IndexError => e
21
+ raise IndexError, 'cookie store unavailable: %s, error: %s' % symbol.inspect, e.message
22
22
  end
23
23
  end
24
24
 
@@ -67,10 +67,8 @@ class HTTP::CookieJar
67
67
  def each(uri = nil) # :yield: cookie
68
68
  now = Time.now
69
69
  if uri
70
- thost = DomainName.new(uri.host)
71
70
  tpath = uri.path
72
71
  @jar.each { |domain, paths|
73
- next unless thost.cookie_domain?(domain)
74
72
  paths.each { |path, hash|
75
73
  next unless HTTP::Cookie.path_match?(path, tpath)
76
74
  hash.delete_if { |name, cookie|
@@ -10,7 +10,7 @@ class HTTP::CookieJar
10
10
  # stored persistently in the SQLite3 database.
11
11
  class MozillaStore < AbstractStore
12
12
  # :stopdoc:
13
- SCHEMA_VERSION = 5
13
+ SCHEMA_VERSION = 7
14
14
 
15
15
  def default_options
16
16
  {
@@ -22,14 +22,11 @@ class HTTP::CookieJar
22
22
 
23
23
  ALL_COLUMNS = %w[
24
24
  baseDomain
25
- appId inBrowserElement
25
+ originAttributes
26
26
  name value
27
27
  host path
28
28
  expiry creationTime lastAccessed
29
29
  isSecure isHttpOnly
30
- ]
31
- UK_COLUMNS = %w[
32
- name host path
33
30
  appId inBrowserElement
34
31
  ]
35
32
 
@@ -95,6 +92,11 @@ class HTTP::CookieJar
95
92
  def initialize(options = nil)
96
93
  super
97
94
 
95
+ @origin_attributes = encode_www_form({}.tap { |params|
96
+ params['appId'] = @app_id if @app_id.nonzero?
97
+ params['inBrowserElement'] = 1 if @in_browser_element
98
+ })
99
+
98
100
  @filename = options[:filename] or raise ArgumentError, ':filename option is missing'
99
101
 
100
102
  @sjar = HTTP::CookieJar::HashStore.new
@@ -134,7 +136,7 @@ class HTTP::CookieJar
134
136
 
135
137
  # Returns the schema version of the database.
136
138
  def schema_version
137
- @schema_version ||= @db.execute("PRAGMA user_version").first[0]
139
+ @schema_version ||= @db.execute("PRAGMA user_version").first["user_version"]
138
140
  rescue SQLite3::SQLException
139
141
  @logger.warn "couldn't get schema version!" if @logger
140
142
  return nil
@@ -147,8 +149,8 @@ class HTTP::CookieJar
147
149
  @schema_version = version
148
150
  end
149
151
 
150
- def create_table
151
- self.schema_version = SCHEMA_VERSION
152
+ def create_table_v5
153
+ self.schema_version = 5
152
154
  @db.execute("DROP TABLE IF EXISTS moz_cookies")
153
155
  @db.execute(<<-'SQL')
154
156
  CREATE TABLE moz_cookies (
@@ -176,6 +178,62 @@ class HTTP::CookieJar
176
178
  SQL
177
179
  end
178
180
 
181
+ def create_table_v6
182
+ self.schema_version = 6
183
+ @db.execute("DROP TABLE IF EXISTS moz_cookies")
184
+ @db.execute(<<-'SQL')
185
+ CREATE TABLE moz_cookies (
186
+ id INTEGER PRIMARY KEY,
187
+ baseDomain TEXT,
188
+ originAttributes TEXT NOT NULL DEFAULT '',
189
+ name TEXT,
190
+ value TEXT,
191
+ host TEXT,
192
+ path TEXT,
193
+ expiry INTEGER,
194
+ lastAccessed INTEGER,
195
+ creationTime INTEGER,
196
+ isSecure INTEGER,
197
+ isHttpOnly INTEGER,
198
+ CONSTRAINT moz_uniqueid UNIQUE (name, host, path, originAttributes)
199
+ )
200
+ SQL
201
+ @db.execute(<<-'SQL')
202
+ CREATE INDEX moz_basedomain
203
+ ON moz_cookies (baseDomain,
204
+ originAttributes);
205
+ SQL
206
+ end
207
+
208
+ def create_table
209
+ self.schema_version = SCHEMA_VERSION
210
+ @db.execute("DROP TABLE IF EXISTS moz_cookies")
211
+ @db.execute(<<-'SQL')
212
+ CREATE TABLE moz_cookies (
213
+ id INTEGER PRIMARY KEY,
214
+ baseDomain TEXT,
215
+ originAttributes TEXT NOT NULL DEFAULT '',
216
+ name TEXT,
217
+ value TEXT,
218
+ host TEXT,
219
+ path TEXT,
220
+ expiry INTEGER,
221
+ lastAccessed INTEGER,
222
+ creationTime INTEGER,
223
+ isSecure INTEGER,
224
+ isHttpOnly INTEGER,
225
+ appId INTEGER DEFAULT 0,
226
+ inBrowserElement INTEGER DEFAULT 0,
227
+ CONSTRAINT moz_uniqueid UNIQUE (name, host, path, originAttributes)
228
+ )
229
+ SQL
230
+ @db.execute(<<-'SQL')
231
+ CREATE INDEX moz_basedomain
232
+ ON moz_cookies (baseDomain,
233
+ originAttributes);
234
+ SQL
235
+ end
236
+
179
237
  def db_prepare(sql)
180
238
  st = @db.prepare(sql)
181
239
  yield st
@@ -226,7 +284,7 @@ class HTTP::CookieJar
226
284
  when 4
227
285
  @db.execute("ALTER TABLE moz_cookies RENAME TO moz_cookies_old")
228
286
  @db.execute("DROP INDEX moz_basedomain")
229
- create_table
287
+ create_table_v5
230
288
  @db.execute(<<-'SQL')
231
289
  INSERT INTO moz_cookies
232
290
  (baseDomain, appId, inBrowserElement, name, value, host, path, expiry,
@@ -236,7 +294,42 @@ class HTTP::CookieJar
236
294
  FROM moz_cookies_old
237
295
  SQL
238
296
  @db.execute("DROP TABLE moz_cookies_old")
297
+ when 5
298
+ @db.execute("ALTER TABLE moz_cookies RENAME TO moz_cookies_old")
299
+ @db.execute("DROP INDEX moz_basedomain")
300
+ create_table_v6
301
+ @db.create_function('CONVERT_TO_ORIGIN_ATTRIBUTES', 2) { |func, appId, inBrowserElement|
302
+ params = {}
303
+ params['appId'] = appId if appId.nonzero?
304
+ params['inBrowserElement'] = inBrowserElement if inBrowserElement.nonzero?
305
+ func.result = encode_www_form(params)
306
+ }
307
+ @db.execute(<<-'SQL')
308
+ INSERT INTO moz_cookies
309
+ (baseDomain, originAttributes, name, value, host, path, expiry,
310
+ lastAccessed, creationTime, isSecure, isHttpOnly)
311
+ SELECT baseDomain,
312
+ CONVERT_TO_ORIGIN_ATTRIBUTES(appId, inBrowserElement),
313
+ name, value, host, path, expiry, lastAccessed, creationTime,
314
+ isSecure, isHttpOnly
315
+ FROM moz_cookies_old
316
+ SQL
317
+ @db.execute("DROP TABLE moz_cookies_old")
318
+ when 6
319
+ @db.execute("ALTER TABLE moz_cookies ADD appId INTEGER DEFAULT 0")
320
+ @db.execute("ALTER TABLE moz_cookies ADD inBrowserElement INTEGER DEFAULT 0")
321
+ @db.create_function('SET_APP_ID', 1) { |func, originAttributes|
322
+ func.result = get_query_param(originAttributes, 'appId').to_i # nil.to_i == 0
323
+ }
324
+ @db.create_function('SET_IN_BROWSER', 1) { |func, originAttributes|
325
+ func.result = get_query_param(originAttributes, 'inBrowserElement').to_i # nil.to_i == 0
326
+ }
327
+ @db.execute(<<-'SQL')
328
+ UPDATE moz_cookies SET appId = SET_APP_ID(originAttributes),
329
+ inBrowserElement = SET_IN_BROWSER(originAttributes)
330
+ SQL
239
331
  @logger.info("Upgraded database to schema version %d" % schema_version) if @logger
332
+ self.schema_version += 1
240
333
  else
241
334
  break
242
335
  end
@@ -259,16 +352,17 @@ class HTTP::CookieJar
259
352
  def db_add(cookie)
260
353
  @stmt[:add].execute({
261
354
  :baseDomain => cookie.domain_name.domain || cookie.domain,
262
- :appId => @app_id,
263
- :inBrowserElement => @in_browser_element ? 1 : 0,
355
+ :originAttributes => @origin_attributes,
264
356
  :name => cookie.name, :value => cookie.value,
265
357
  :host => cookie.dot_domain,
266
358
  :path => cookie.path,
267
359
  :expiry => cookie.expires_at.to_i,
268
- :creationTime => cookie.created_at.to_i,
269
- :lastAccessed => cookie.accessed_at.to_i,
360
+ :creationTime => serialize_usectime(cookie.created_at),
361
+ :lastAccessed => serialize_usectime(cookie.accessed_at),
270
362
  :isSecure => cookie.secure? ? 1 : 0,
271
363
  :isHttpOnly => cookie.httponly? ? 1 : 0,
364
+ :appId => @app_id,
365
+ :inBrowserElement => @in_browser_element ? 1 : 0,
272
366
  })
273
367
  cleanup if (@gc_index += 1) >= @gc_threshold
274
368
 
@@ -295,6 +389,36 @@ class HTTP::CookieJar
295
389
  self
296
390
  end
297
391
 
392
+ if RUBY_VERSION >= '1.9'
393
+ def encode_www_form(enum)
394
+ URI.encode_www_form(enum)
395
+ end
396
+
397
+ def get_query_param(str, key)
398
+ URI.decode_www_form(str).find { |k, v|
399
+ break v if k == key
400
+ }
401
+ end
402
+ else
403
+ require 'cgi'
404
+
405
+ def encode_www_form(enum)
406
+ enum.map { |k, v| "#{CGI.escape(k)}=#{CGI.escape(v)}" }.join('&')
407
+ end
408
+
409
+ def get_query_param(str, key)
410
+ CGI.parse(str)[key].first
411
+ end
412
+ end
413
+
414
+ def serialize_usectime(time)
415
+ time ? (time.to_f * 1e6).floor : 0
416
+ end
417
+
418
+ def deserialize_usectime(value)
419
+ Time.at(value ? value / 1e6 : 0)
420
+ end
421
+
298
422
  public
299
423
 
300
424
  def add(cookie)
@@ -337,7 +461,6 @@ class HTTP::CookieJar
337
461
  now = Time.now
338
462
  if uri
339
463
  thost = DomainName.new(uri.host)
340
- tpath = uri.path
341
464
 
342
465
  @stmt[:cookies_for_domain].execute({
343
466
  :baseDomain => thost.domain || thost.hostname,
@@ -355,8 +478,8 @@ class HTTP::CookieJar
355
478
  attrs[:domain] = row['host']
356
479
  attrs[:path] = row['path']
357
480
  attrs[:expires_at] = Time.at(row['expiry'])
358
- attrs[:accessed_at] = Time.at(row['lastAccessed'] || 0)
359
- attrs[:created_at] = Time.at(row['creationTime'] || 0)
481
+ attrs[:accessed_at] = deserialize_usectime(row['lastAccessed'])
482
+ attrs[:created_at] = deserialize_usectime(row['creationTime'])
360
483
  attrs[:secure] = secure
361
484
  attrs[:httponly] = row['isHttpOnly'] != 0
362
485
  })
@@ -364,7 +487,7 @@ class HTTP::CookieJar
364
487
  if cookie.valid_for_uri?(uri)
365
488
  cookie.accessed_at = now
366
489
  @stmt[:update_lastaccessed].execute({
367
- 'lastAccessed' => now.to_i,
490
+ 'lastAccessed' => serialize_usectime(now),
368
491
  'id' => row['id'],
369
492
  })
370
493
  yield cookie
@@ -383,8 +506,8 @@ class HTTP::CookieJar
383
506
  attrs[:domain] = row['host']
384
507
  attrs[:path] = row['path']
385
508
  attrs[:expires_at] = Time.at(row['expiry'])
386
- attrs[:accessed_at] = Time.at(row['lastAccessed'] || 0)
387
- attrs[:created_at] = Time.at(row['creationTime'] || 0)
509
+ attrs[:accessed_at] = deserialize_usectime(row['lastAccessed'])
510
+ attrs[:created_at] = deserialize_usectime(row['creationTime'])
388
511
  attrs[:secure] = row['isSecure'] != 0
389
512
  attrs[:httponly] = row['isHttpOnly'] != 0
390
513
  })
@@ -21,7 +21,7 @@ class HTTP::CookieJar::YAMLSaver < HTTP::CookieJar::AbstractSaver
21
21
 
22
22
  def load(io, jar)
23
23
  begin
24
- data = YAML.load(io)
24
+ data = load_yaml(io)
25
25
  rescue ArgumentError => e
26
26
  case e.message
27
27
  when %r{\Aundefined class/module Mechanize::}
@@ -31,7 +31,7 @@ class HTTP::CookieJar::YAMLSaver < HTTP::CookieJar::AbstractSaver
31
31
  yaml = io.read
32
32
  # a gross hack
33
33
  yaml.gsub!(%r{^( [^ ].*:) !ruby/object:Mechanize::Cookie$}, "\\1")
34
- data = YAML.load(yaml)
34
+ data = load_yaml(yaml)
35
35
  rescue Errno::ESPIPE
36
36
  @logger.warn "could not rewind the stream for conversion" if @logger
37
37
  rescue ArgumentError
@@ -73,4 +73,14 @@ class HTTP::CookieJar::YAMLSaver < HTTP::CookieJar::AbstractSaver
73
73
  def default_options
74
74
  {}
75
75
  end
76
+
77
+ if YAML.name == 'Psych' && Psych::VERSION >= '3.1'
78
+ def load_yaml(yaml)
79
+ YAML.safe_load(yaml, :permitted_classes => %w[Time HTTP::Cookie Mechanize::Cookie DomainName], :aliases => true)
80
+ end
81
+ else
82
+ def load_yaml(yaml)
83
+ YAML.load(yaml)
84
+ end
85
+ end
76
86
  end
@@ -1,5 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  require File.expand_path('helper', File.dirname(__FILE__))
3
+ require 'psych' if !defined?(YAML) && RUBY_VERSION == "1.9.2"
4
+ require 'yaml'
3
5
 
4
6
  class TestHTTPCookie < Test::Unit::TestCase
5
7
  def setup
@@ -441,17 +443,28 @@ class TestHTTPCookie < Test::Unit::TestCase
441
443
  ['Bar', 'value 2'],
442
444
  ['Baz', 'value3'],
443
445
  ['Bar', 'value"4'],
446
+ ['Quux', 'x, value=5'],
444
447
  ]
445
448
 
446
449
  cookie_value = HTTP::Cookie.cookie_value(pairs.map { |name, value|
447
450
  HTTP::Cookie.new(:name => name, :value => value)
448
451
  })
449
452
 
450
- assert_equal 'Foo=value1; Bar="value 2"; Baz=value3; Bar="value\\"4"', cookie_value
453
+ assert_equal 'Foo=value1; Bar="value 2"; Baz=value3; Bar="value\\"4"; Quux="x, value=5"', cookie_value
451
454
 
452
455
  hash = HTTP::Cookie.cookie_value_to_hash(cookie_value)
453
456
 
454
- assert_equal 3, hash.size
457
+ assert_equal pairs.map(&:first).uniq.size, hash.size
458
+
459
+ hash.each_pair { |name, value|
460
+ _, pvalue = pairs.assoc(name)
461
+ assert_equal pvalue, value
462
+ }
463
+
464
+ # Do not treat comma in a Cookie header value as separator; see CVE-2016-7401
465
+ hash = HTTP::Cookie.cookie_value_to_hash('Quux=x, value=5; Foo=value1; Bar="value 2"; Baz=value3; Bar="value\\"4"')
466
+
467
+ assert_equal pairs.map(&:first).uniq.size, hash.size
455
468
 
456
469
  hash.each_pair { |name, value|
457
470
  _, pvalue = pairs.assoc(name)
@@ -1062,6 +1075,16 @@ class TestHTTPCookie < Test::Unit::TestCase
1062
1075
  }
1063
1076
  end
1064
1077
 
1078
+ if YAML.name == 'Psych' && Psych::VERSION >= '3.1'
1079
+ private def load_yaml(yaml)
1080
+ YAML.safe_load(yaml, :permitted_classes => %w[Time HTTP::Cookie Mechanize::Cookie DomainName], :aliases => true)
1081
+ end
1082
+ else
1083
+ private def load_yaml(yaml)
1084
+ YAML.load(yaml)
1085
+ end
1086
+ end
1087
+
1065
1088
  def test_yaml_expires
1066
1089
  require 'yaml'
1067
1090
  cookie = HTTP::Cookie.new(cookie_values)
@@ -1069,29 +1092,29 @@ class TestHTTPCookie < Test::Unit::TestCase
1069
1092
  assert_equal false, cookie.session?
1070
1093
  assert_equal nil, cookie.max_age
1071
1094
 
1072
- ycookie = YAML.load(cookie.to_yaml)
1095
+ ycookie = load_yaml(cookie.to_yaml)
1073
1096
  assert_equal false, ycookie.session?
1074
1097
  assert_equal nil, ycookie.max_age
1075
1098
  assert_in_delta cookie.expires, ycookie.expires, 1
1076
1099
 
1077
1100
  cookie.expires = nil
1078
- ycookie = YAML.load(cookie.to_yaml)
1101
+ ycookie = load_yaml(cookie.to_yaml)
1079
1102
  assert_equal true, ycookie.session?
1080
1103
  assert_equal nil, ycookie.max_age
1081
1104
 
1082
1105
  cookie.expires = Time.now + 3600
1083
- ycookie = YAML.load(cookie.to_yaml)
1106
+ ycookie = load_yaml(cookie.to_yaml)
1084
1107
  assert_equal false, ycookie.session?
1085
1108
  assert_equal nil, ycookie.max_age
1086
1109
  assert_in_delta cookie.expires, ycookie.expires, 1
1087
1110
 
1088
1111
  cookie.max_age = 3600
1089
- ycookie = YAML.load(cookie.to_yaml)
1112
+ ycookie = load_yaml(cookie.to_yaml)
1090
1113
  assert_equal false, ycookie.session?
1091
1114
  assert_in_delta cookie.created_at + 3600, ycookie.expires, 1
1092
1115
 
1093
1116
  cookie.max_age = nil
1094
- ycookie = YAML.load(cookie.to_yaml)
1117
+ ycookie = load_yaml(cookie.to_yaml)
1095
1118
  assert_equal true, ycookie.session?
1096
1119
  assert_equal nil, ycookie.expires
1097
1120
  end
@@ -20,11 +20,7 @@ module TestHTTPCookieJar
20
20
  assert_raises(NameError) {
21
21
  HTTP::CookieJar::ErroneousStore
22
22
  }
23
- if RUBY_VERSION >= "1.9"
24
- assert_includes $LOADED_FEATURES, rb
25
- else
26
- assert_includes $LOADED_FEATURES, rb[(dir.size + 1)..-1]
27
- end
23
+ assert($LOADED_FEATURES.any? { |file| FileTest.identical?(file, rb) })
28
24
  }
29
25
  end
30
26
 
@@ -45,11 +41,7 @@ module TestHTTPCookieJar
45
41
  assert_raises(NameError) {
46
42
  HTTP::CookieJar::ErroneousSaver
47
43
  }
48
- if RUBY_VERSION >= "1.9"
49
- assert_includes $LOADED_FEATURES, rb
50
- else
51
- assert_includes $LOADED_FEATURES, rb[(dir.size + 1)..-1]
52
- end
44
+ assert($LOADED_FEATURES.any? { |file| FileTest.identical?(file, rb) })
53
45
  }
54
46
  end
55
47
  end
@@ -139,6 +131,17 @@ module TestHTTPCookieJar
139
131
  assert_equal(0, @jar.cookies(URI('http://www.rubyforge.org/')).length)
140
132
  end
141
133
 
134
+ def test_host_only_with_unqualified_hostname
135
+ @jar.add(HTTP::Cookie.new(cookie_values(
136
+ :origin => 'http://localhost/', :domain => 'localhost', :for_domain => false)))
137
+
138
+ assert_equal(1, @jar.cookies(URI('http://localhost/')).length)
139
+
140
+ assert_equal(1, @jar.cookies(URI('http://Localhost/')).length)
141
+
142
+ assert_equal(1, @jar.cookies(URI('https://Localhost/')).length)
143
+ end
144
+
142
145
  def test_empty_value
143
146
  url = URI 'http://rubyforge.org/'
144
147
  values = cookie_values(:value => "")
metadata CHANGED
@@ -1,114 +1,114 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: http-cookie
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Akinori MUSHA
8
8
  - Aaron Patterson
9
9
  - Eric Hodel
10
10
  - Mike Dalessio
11
- autorequire:
11
+ autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2013-09-10 00:00:00.000000000 Z
14
+ date: 2022-05-25 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: domain_name
18
18
  requirement: !ruby/object:Gem::Requirement
19
19
  requirements:
20
- - - ~>
20
+ - - "~>"
21
21
  - !ruby/object:Gem::Version
22
22
  version: '0.5'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - ~>
27
+ - - "~>"
28
28
  - !ruby/object:Gem::Version
29
29
  version: '0.5'
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: sqlite3
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  requirements:
34
- - - ~>
34
+ - - "~>"
35
35
  - !ruby/object:Gem::Version
36
- version: 1.3.3
36
+ version: '1.3'
37
37
  type: :development
38
38
  prerelease: false
39
39
  version_requirements: !ruby/object:Gem::Requirement
40
40
  requirements:
41
- - - ~>
41
+ - - "~>"
42
42
  - !ruby/object:Gem::Version
43
- version: 1.3.3
43
+ version: '1.3'
44
44
  - !ruby/object:Gem::Dependency
45
45
  name: bundler
46
46
  requirement: !ruby/object:Gem::Requirement
47
47
  requirements:
48
- - - '>='
48
+ - - ">="
49
49
  - !ruby/object:Gem::Version
50
50
  version: 1.2.0
51
51
  type: :development
52
52
  prerelease: false
53
53
  version_requirements: !ruby/object:Gem::Requirement
54
54
  requirements:
55
- - - '>='
55
+ - - ">="
56
56
  - !ruby/object:Gem::Version
57
57
  version: 1.2.0
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: test-unit
60
60
  requirement: !ruby/object:Gem::Requirement
61
61
  requirements:
62
- - - '>='
62
+ - - ">="
63
63
  - !ruby/object:Gem::Version
64
64
  version: 2.4.3
65
65
  type: :development
66
66
  prerelease: false
67
67
  version_requirements: !ruby/object:Gem::Requirement
68
68
  requirements:
69
- - - '>='
69
+ - - ">="
70
70
  - !ruby/object:Gem::Version
71
71
  version: 2.4.3
72
72
  - !ruby/object:Gem::Dependency
73
73
  name: rake
74
74
  requirement: !ruby/object:Gem::Requirement
75
75
  requirements:
76
- - - '>='
76
+ - - ">="
77
77
  - !ruby/object:Gem::Version
78
78
  version: 0.9.2.2
79
79
  type: :development
80
80
  prerelease: false
81
81
  version_requirements: !ruby/object:Gem::Requirement
82
82
  requirements:
83
- - - '>='
83
+ - - ">="
84
84
  - !ruby/object:Gem::Version
85
85
  version: 0.9.2.2
86
86
  - !ruby/object:Gem::Dependency
87
87
  name: rdoc
88
88
  requirement: !ruby/object:Gem::Requirement
89
89
  requirements:
90
- - - '>'
90
+ - - ">"
91
91
  - !ruby/object:Gem::Version
92
92
  version: 2.4.2
93
93
  type: :development
94
94
  prerelease: false
95
95
  version_requirements: !ruby/object:Gem::Requirement
96
96
  requirements:
97
- - - '>'
97
+ - - ">"
98
98
  - !ruby/object:Gem::Version
99
99
  version: 2.4.2
100
100
  - !ruby/object:Gem::Dependency
101
101
  name: simplecov
102
102
  requirement: !ruby/object:Gem::Requirement
103
103
  requirements:
104
- - - '>='
104
+ - - ">="
105
105
  - !ruby/object:Gem::Version
106
106
  version: '0'
107
107
  type: :development
108
108
  prerelease: false
109
109
  version_requirements: !ruby/object:Gem::Requirement
110
110
  requirements:
111
- - - '>='
111
+ - - ">="
112
112
  - !ruby/object:Gem::Version
113
113
  version: '0'
114
114
  description: HTTP::Cookie is a Ruby library to handle HTTP Cookies based on RFC 6265. It
@@ -127,8 +127,8 @@ extra_rdoc_files:
127
127
  - README.md
128
128
  - LICENSE.txt
129
129
  files:
130
- - .gitignore
131
- - .travis.yml
130
+ - ".github/workflows/ci.yml"
131
+ - ".gitignore"
132
132
  - CHANGELOG.md
133
133
  - Gemfile
134
134
  - LICENSE.txt
@@ -156,24 +156,23 @@ homepage: https://github.com/sparklemotion/http-cookie
156
156
  licenses:
157
157
  - MIT
158
158
  metadata: {}
159
- post_install_message:
159
+ post_install_message:
160
160
  rdoc_options: []
161
161
  require_paths:
162
162
  - lib
163
163
  required_ruby_version: !ruby/object:Gem::Requirement
164
164
  requirements:
165
- - - '>='
165
+ - - ">="
166
166
  - !ruby/object:Gem::Version
167
167
  version: '0'
168
168
  required_rubygems_version: !ruby/object:Gem::Requirement
169
169
  requirements:
170
- - - '>='
170
+ - - ">="
171
171
  - !ruby/object:Gem::Version
172
172
  version: '0'
173
173
  requirements: []
174
- rubyforge_project:
175
- rubygems_version: 2.0.3
176
- signing_key:
174
+ rubygems_version: 3.3.14
175
+ signing_key:
177
176
  specification_version: 4
178
177
  summary: A Ruby library to handle HTTP Cookies based on RFC 6265
179
178
  test_files:
data/.travis.yml DELETED
@@ -1,17 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 1.8.7
4
- - ree
5
- - 1.9.3
6
- - 2.0.0
7
- - ruby-head
8
- - jruby-18mode
9
- - jruby-19mode
10
- - jruby-head
11
- - rbx-18mode
12
- - rbx-19mode
13
- matrix:
14
- allow_failures:
15
- - rvm: ruby-head
16
- - rvm: rbx-18mode
17
- - rvm: rbx-19mode