diff --git a/lib/http/cookie.rb b/lib/http/cookie.rb index 6f30477..c76524f 100644 --- a/lib/http/cookie.rb +++ b/lib/http/cookie.rb @@ -9,6 +9,9 @@ end # This class is used to represent an HTTP Cookie. class HTTP::Cookie + # Maximum number of bytes per cookie (RFC 6265 6.1 requires 4096 at least) + MAX_LENGTH = 4096 + PERSISTENT_PROPERTIES = %w[ name value domain for_domain path @@ -153,6 +156,11 @@ class HTTP::Cookie [].tap { |cookies| set_cookie.split(/,(?=[^;,]*=)|,$/).each { |c| + if c.bytesize > MAX_LENGTH + logger.warn("Cookie definition too long: #{c}") if logger + next + end + cookie_elem = c.split(/;+/) first_elem = cookie_elem.shift first_elem.strip! diff --git a/test/test_http_cookie.rb b/test/test_http_cookie.rb index e1f7d18..bf9edba 100644 --- a/test/test_http_cookie.rb +++ b/test/test_http_cookie.rb @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- require File.expand_path('helper', File.dirname(__FILE__)) class TestHTTPCookie < Test::Unit::TestCase @@ -79,6 +80,19 @@ class TestHTTPCookie < Test::Unit::TestCase end end + def test_parse_too_long_cookie + uri = URI.parse 'http://example' + + cookie_str = "foo=#{'クッキー' * 340}; path=/ab/" + assert_equal(HTTP::Cookie::MAX_LENGTH - 1, cookie_str.bytesize) + + assert_equal 1, HTTP::Cookie.parse(cookie_str, :origin => uri).size + + assert_equal 1, HTTP::Cookie.parse(cookie_str.sub(';', 'x;'), :origin => uri).size + + assert_equal 0, HTTP::Cookie.parse(cookie_str.sub(';', 'xx;'), :origin => uri).size + end + def test_parse_quoted cookie_str = "quoted=\"value\"; Expires=Sun, 06 Nov 2011 00:11:18 GMT; Path=/"