summaryrefslogtreecommitdiff
path: root/test/cgi
diff options
context:
space:
mode:
Diffstat (limited to 'test/cgi')
-rw-r--r--test/cgi/test_cgi_cookie.rb85
-rw-r--r--test/cgi/test_cgi_header.rb8
-rw-r--r--test/cgi/test_cgi_util.rb80
3 files changed, 170 insertions, 3 deletions
diff --git a/test/cgi/test_cgi_cookie.rb b/test/cgi/test_cgi_cookie.rb
index 985cc0d7a1..eadae45313 100644
--- a/test/cgi/test_cgi_cookie.rb
+++ b/test/cgi/test_cgi_cookie.rb
@@ -60,6 +60,27 @@ class CGICookieTest < Test::Unit::TestCase
end
+ def test_cgi_cookie_new_with_domain
+ h = {'name'=>'name1', 'value'=>'value1'}
+ cookie = CGI::Cookie.new(h.merge('domain'=>'a.example.com'))
+ assert_equal('a.example.com', cookie.domain)
+
+ cookie = CGI::Cookie.new(h.merge('domain'=>'.example.com'))
+ assert_equal('.example.com', cookie.domain)
+
+ cookie = CGI::Cookie.new(h.merge('domain'=>'1.example.com'))
+ assert_equal('1.example.com', cookie.domain, 'enhanced by RFC 1123')
+
+ assert_raise(ArgumentError) {
+ CGI::Cookie.new(h.merge('domain'=>'-a.example.com'))
+ }
+
+ assert_raise(ArgumentError) {
+ CGI::Cookie.new(h.merge('domain'=>'a-.example.com'))
+ }
+ end
+
+
def test_cgi_cookie_scriptname
cookie = CGI::Cookie.new('name1', 'value1')
assert_equal('', cookie.path)
@@ -118,6 +139,70 @@ class CGICookieTest < Test::Unit::TestCase
end
+ def test_cgi_cookie_domain_injection_into_name
+ name = "a=b; domain=example.com;"
+ path = "/"
+ domain = "example.jp"
+ assert_raise(ArgumentError) do
+ CGI::Cookie.new('name' => name,
+ 'value' => "value",
+ 'domain' => domain,
+ 'path' => path)
+ end
+ end
+
+
+ def test_cgi_cookie_newline_injection_into_name
+ name = "a=b;\r\nLocation: http://example.com#"
+ path = "/"
+ domain = "example.jp"
+ assert_raise(ArgumentError) do
+ CGI::Cookie.new('name' => name,
+ 'value' => "value",
+ 'domain' => domain,
+ 'path' => path)
+ end
+ end
+
+
+ def test_cgi_cookie_multibyte_injection_into_name
+ name = "a=b;\u3042"
+ path = "/"
+ domain = "example.jp"
+ assert_raise(ArgumentError) do
+ CGI::Cookie.new('name' => name,
+ 'value' => "value",
+ 'domain' => domain,
+ 'path' => path)
+ end
+ end
+
+
+ def test_cgi_cookie_injection_into_path
+ name = "name"
+ path = "/; samesite=none"
+ domain = "example.jp"
+ assert_raise(ArgumentError) do
+ CGI::Cookie.new('name' => name,
+ 'value' => "value",
+ 'domain' => domain,
+ 'path' => path)
+ end
+ end
+
+
+ def test_cgi_cookie_injection_into_domain
+ name = "name"
+ path = "/"
+ domain = "example.jp; samesite=none"
+ assert_raise(ArgumentError) do
+ CGI::Cookie.new('name' => name,
+ 'value' => "value",
+ 'domain' => domain,
+ 'path' => path)
+ end
+ end
+
instance_methods.each do |method|
private method if method =~ /^test_(.*)/ && $1 != ENV['TEST']
diff --git a/test/cgi/test_cgi_header.rb b/test/cgi/test_cgi_header.rb
index bab2d0348a..ec2f4deb72 100644
--- a/test/cgi/test_cgi_header.rb
+++ b/test/cgi/test_cgi_header.rb
@@ -176,6 +176,14 @@ class CGIHeaderTest < Test::Unit::TestCase
end
+ def test_cgi_http_header_crlf_injection
+ cgi = CGI.new
+ assert_raise(RuntimeError) { cgi.http_header("text/xhtml\r\nBOO") }
+ assert_raise(RuntimeError) { cgi.http_header("type" => "text/xhtml\r\nBOO") }
+ assert_raise(RuntimeError) { cgi.http_header("status" => "200 OK\r\nBOO") }
+ assert_raise(RuntimeError) { cgi.http_header("location" => "text/xhtml\r\nBOO") }
+ end
+
instance_methods.each do |method|
private method if method =~ /^test_(.*)/ && $1 != ENV['TEST']
diff --git a/test/cgi/test_cgi_util.rb b/test/cgi/test_cgi_util.rb
index 5baf87db75..b0612fc87d 100644
--- a/test/cgi/test_cgi_util.rb
+++ b/test/cgi/test_cgi_util.rb
@@ -23,7 +23,6 @@ class CGIUtilTest < Test::Unit::TestCase
ENV.update(@environ)
end
-
def test_cgi_escape
assert_equal('%26%3C%3E%22+%E3%82%86%E3%82%93%E3%82%86%E3%82%93', CGI.escape(@str1))
assert_equal('%26%3C%3E%22+%E3%82%86%E3%82%93%E3%82%86%E3%82%93'.ascii_only?, CGI.escape(@str1).ascii_only?) if defined?(::Encoding)
@@ -70,6 +69,63 @@ class CGIUtilTest < Test::Unit::TestCase
end;
end
+ def test_cgi_escapeURIComponent
+ assert_equal('%26%3C%3E%22%20%E3%82%86%E3%82%93%E3%82%86%E3%82%93', CGI.escapeURIComponent(@str1))
+ assert_equal('%26%3C%3E%22%20%E3%82%86%E3%82%93%E3%82%86%E3%82%93'.ascii_only?, CGI.escapeURIComponent(@str1).ascii_only?) if defined?(::Encoding)
+ end
+
+ def test_cgi_escape_uri_component
+ assert_equal('%26%3C%3E%22%20%E3%82%86%E3%82%93%E3%82%86%E3%82%93', CGI.escape_uri_component(@str1))
+ end
+
+ def test_cgi_escapeURIComponent_with_unreserved_characters
+ assert_equal("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~",
+ CGI.escapeURIComponent("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~"),
+ "should not encode any unreserved characters, as per RFC3986 Section 2.3")
+ end
+
+ def test_cgi_escapeURIComponent_with_invalid_byte_sequence
+ assert_equal('%C0%3C%3C', CGI.escapeURIComponent("\xC0\<\<".dup.force_encoding("UTF-8")))
+ end
+
+ def test_cgi_escapeURIComponent_preserve_encoding
+ assert_equal(Encoding::US_ASCII, CGI.escapeURIComponent("\xC0\<\<".dup.force_encoding("US-ASCII")).encoding)
+ assert_equal(Encoding::ASCII_8BIT, CGI.escapeURIComponent("\xC0\<\<".dup.force_encoding("ASCII-8BIT")).encoding)
+ assert_equal(Encoding::UTF_8, CGI.escapeURIComponent("\xC0\<\<".dup.force_encoding("UTF-8")).encoding)
+ end
+
+ def test_cgi_unescapeURIComponent
+ str = CGI.unescapeURIComponent('%26%3C%3E%22%20%E3%82%86%E3%82%93%E3%82%86%E3%82%93')
+ assert_equal(@str1, str)
+ return unless defined?(::Encoding)
+
+ assert_equal("foo+bar", CGI.unescapeURIComponent("foo+bar"))
+
+ assert_equal(@str1.encoding, str.encoding)
+ assert_equal("\u{30E1 30E2 30EA 691C 7D22}", CGI.unescapeURIComponent("\u{30E1 30E2 30EA}%E6%A4%9C%E7%B4%A2"))
+ end
+
+ def test_cgi_unescape_uri_component
+ str = CGI.unescape_uri_component('%26%3C%3E%22%20%E3%82%86%E3%82%93%E3%82%86%E3%82%93')
+ assert_equal(@str1, str)
+ end
+
+ def test_cgi_unescapeURIComponent_preserve_encoding
+ assert_equal(Encoding::US_ASCII, CGI.unescapeURIComponent("%C0%3C%3C".dup.force_encoding("US-ASCII")).encoding)
+ assert_equal(Encoding::ASCII_8BIT, CGI.unescapeURIComponent("%C0%3C%3C".dup.force_encoding("ASCII-8BIT")).encoding)
+ assert_equal(Encoding::UTF_8, CGI.unescapeURIComponent("%C0%3C%3C".dup.force_encoding("UTF-8")).encoding)
+ end
+
+ def test_cgi_unescapeURIComponent_accept_charset
+ return unless defined?(::Encoding)
+
+ assert_raise(TypeError) {CGI.unescapeURIComponent('', nil)}
+ assert_separately(%w[-rcgi/util], "#{<<-"begin;"}\n#{<<-"end;"}")
+ begin;
+ assert_equal("", CGI.unescapeURIComponent(''))
+ end;
+ end
+
def test_cgi_pretty
assert_equal("<HTML>\n <BODY>\n </BODY>\n</HTML>\n",CGI.pretty("<HTML><BODY></BODY></HTML>"))
assert_equal("<HTML>\n\t<BODY>\n\t</BODY>\n</HTML>\n",CGI.pretty("<HTML><BODY></BODY></HTML>","\t"))
@@ -130,6 +186,22 @@ class CGIUtilTest < Test::Unit::TestCase
assert_equal('&<&amp>&quot&abcdefghijklmn', CGI.unescapeHTML('&&lt;&amp&gt;&quot&abcdefghijklmn'))
end
+ module UnescapeHTMLTests
+ def test_cgi_unescapeHTML_following_known_first_letter
+ assert_equal('&a>&q>&l>&g>', CGI.unescapeHTML('&a&gt;&q&gt;&l&gt;&g&gt;'))
+ end
+
+ def test_cgi_unescapeHTML_following_number_sign
+ assert_equal('&#>&#x>', CGI.unescapeHTML('&#&gt;&#x&gt;'))
+ end
+
+ def test_cgi_unescapeHTML_following_invalid_numeric
+ assert_equal('&#1114112>&#x110000>', CGI.unescapeHTML('&#1114112&gt;&#x110000&gt;'))
+ end
+ end
+
+ include UnescapeHTMLTests
+
Encoding.list.each do |enc|
begin
escaped = "&#39;&amp;&quot;&gt;&lt;".encode(enc)
@@ -215,7 +287,7 @@ class CGIUtilPureRubyTest < Test::Unit::TestCase
remove_method :escapeHTML
alias _unescapeHTML unescapeHTML
remove_method :unescapeHTML
- end
+ end if defined?(CGI::Escape)
end
def teardown
@@ -224,9 +296,11 @@ class CGIUtilPureRubyTest < Test::Unit::TestCase
remove_method :_escapeHTML
alias unescapeHTML _unescapeHTML
remove_method :_unescapeHTML
- end
+ end if defined?(CGI::Escape)
end
+ include CGIUtilTest::UnescapeHTMLTests
+
def test_cgi_escapeHTML_with_invalid_byte_sequence
assert_equal("&lt;\xA4??&gt;", CGI.escapeHTML(%[<\xA4??>]))
end