Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

don't allow bad characters in header values following LWS

  • Loading branch information...
commit 62791f12d576ecd057a60b5fbe4d17901c2a00aa 1 parent 02c627e
@matsadler authored
Showing with 57 additions and 8 deletions.
  1. +14 −8 lib/http_tools/parser.rb
  2. +43 −0 test/parser/response_test.rb
View
22 lib/http_tools/parser.rb
@@ -445,15 +445,18 @@ def value
end
def value_extention
- if @buffer.check(/[^ \t]/)
+ if @buffer.check(/[^ \t]/i)
key_or_newline
- elsif value_extra = @buffer.scan(/[ \t]+[^\x00\n\x7f]*\n/)
- value_extra.sub!(/^[ \t]+/, SPACE)
+ elsif value_extra = @buffer.scan(/[ \t]+[^\x00\n\x7f]*\n/i)
+ value_extra.sub!(/^[ \t]+/i, SPACE)
value_extra.chop!
(@header[@last_key] << value_extra).strip!
value_extention
- else
+ elsif @buffer.eos? || @buffer.check(/[ \t]+[^\x00\n\x7f]*\Z/i)
:value_extention
+ else
+ @buffer.skip(/[ \t]+[^\x00\n\x7f]*/i)
+ raise ParseError.new("Illegal character in field body at " + posstr)
end
end
@@ -578,15 +581,18 @@ def trailer_value
end
def trailer_value_extention
- if @buffer.check(/[^ \t]/)
+ if @buffer.check(/[^ \t]/i)
trailer_key_or_newline
- elsif value_extra = @buffer.scan(/[ \t]+[^\x00\n\x7f]*\n/)
- value_extra.sub!(/^[ \t]+/, SPACE)
+ elsif value_extra = @buffer.scan(/[ \t]+[^\x00\n\x7f]*\n/i)
+ value_extra.sub!(/^[ \t]+/i, SPACE)
value_extra.chop!
(@trailer[@last_key] << value_extra).strip!
trailer_value_extention
- else
+ elsif @buffer.eos? || @buffer.check(/[ \t]+[^\x00\n\x7f]*\Z/i)
:trailer_value_extention
+ else
+ @buffer.skip(/[ \t]+[^\x00\n\x7f]*/i)
+ raise ParseError.new("Illegal character in field body at " + posstr)
end
end
View
43 test/parser/response_test.rb
@@ -290,6 +290,26 @@ def test_header_value_separated_by_newline
assert_equal({"Content-Type" => "text/html; charset=utf-8"}, headers)
end
+ def test_multi_line_header_invalid_value
+ parser = HTTPTools::Parser.new
+
+ parser << "HTTP/1.1 200 OK\r\n"
+ parser << "Content-Type: text/html;\r\n"
+
+ error = assert_raise(HTTPTools::ParseError) do
+ parser << " charset=\0\r\n\r\n"
+ end
+
+ return unless "".respond_to?(:lines)
+ null = "\000".dump.gsub(/"/, "")
+ assert_equal(<<-MESSAGE.chomp, error.message)
+Illegal character in field body at line 3, char 10
+
+ charset=#{null}\\r\\n
+ ^
+ MESSAGE
+ end
+
def test_header_value_leading_and_trailing_whitespace_is_stripped
parser = HTTPTools::Parser.new
headers = nil
@@ -1203,6 +1223,29 @@ def test_trailer_value_separated_by_newline
assert_equal({"X-Test" => "one two"}, trailer)
end
+ def test_multi_line_trailer_invalid_value
+ parser = HTTPTools::Parser.new
+
+ parser << "HTTP/1.1 200 OK\r\n"
+ parser << "Transfer-Encoding: chunked\r\n"
+ parser << "Trailer: X-Test\r\n\r\n"
+ parser << "14\r\n<h1>Hello world</h1>\r\n0\r\n"
+ parser << "X-Test: one\r\n"
+
+ error = assert_raise(HTTPTools::ParseError) do
+ parser << " \0two\r\n"
+ end
+
+ return unless "".respond_to?(:lines)
+ null = "\000".dump.gsub(/"/, "")
+ assert_equal(<<-MESSAGE.chomp, error.message)
+Illegal character in field body at line 9, char 2
+
+ #{null}two\\r\\n
+ ^
+ MESSAGE
+ end
+
def test_trailer_value_leading_and_trailing_whitespace_is_stripped
parser = HTTPTools::Parser.new
trailer = nil
Please sign in to comment.
Something went wrong with that request. Please try again.