Skip to content

Commit

Permalink
don't allow bad characters in header values following LWS
Browse files Browse the repository at this point in the history
  • Loading branch information
matsadler committed Dec 20, 2011
1 parent 02c627e commit 62791f1
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 8 deletions.
22 changes: 14 additions & 8 deletions lib/http_tools/parser.rb
Expand Up @@ -445,15 +445,18 @@ def value
end end


def value_extention def value_extention
if @buffer.check(/[^ \t]/) if @buffer.check(/[^ \t]/i)
key_or_newline key_or_newline
elsif value_extra = @buffer.scan(/[ \t]+[^\x00\n\x7f]*\n/) elsif value_extra = @buffer.scan(/[ \t]+[^\x00\n\x7f]*\n/i)
value_extra.sub!(/^[ \t]+/, SPACE) value_extra.sub!(/^[ \t]+/i, SPACE)
value_extra.chop! value_extra.chop!
(@header[@last_key] << value_extra).strip! (@header[@last_key] << value_extra).strip!
value_extention value_extention
else elsif @buffer.eos? || @buffer.check(/[ \t]+[^\x00\n\x7f]*\Z/i)
:value_extention :value_extention
else
@buffer.skip(/[ \t]+[^\x00\n\x7f]*/i)
raise ParseError.new("Illegal character in field body at " + posstr)
end end
end end


Expand Down Expand Up @@ -578,15 +581,18 @@ def trailer_value
end end


def trailer_value_extention def trailer_value_extention
if @buffer.check(/[^ \t]/) if @buffer.check(/[^ \t]/i)
trailer_key_or_newline trailer_key_or_newline
elsif value_extra = @buffer.scan(/[ \t]+[^\x00\n\x7f]*\n/) elsif value_extra = @buffer.scan(/[ \t]+[^\x00\n\x7f]*\n/i)
value_extra.sub!(/^[ \t]+/, SPACE) value_extra.sub!(/^[ \t]+/i, SPACE)
value_extra.chop! value_extra.chop!
(@trailer[@last_key] << value_extra).strip! (@trailer[@last_key] << value_extra).strip!
trailer_value_extention trailer_value_extention
else elsif @buffer.eos? || @buffer.check(/[ \t]+[^\x00\n\x7f]*\Z/i)
:trailer_value_extention :trailer_value_extention
else
@buffer.skip(/[ \t]+[^\x00\n\x7f]*/i)
raise ParseError.new("Illegal character in field body at " + posstr)
end end
end end


Expand Down
43 changes: 43 additions & 0 deletions test/parser/response_test.rb
Expand Up @@ -290,6 +290,26 @@ def test_header_value_separated_by_newline
assert_equal({"Content-Type" => "text/html; charset=utf-8"}, headers) assert_equal({"Content-Type" => "text/html; charset=utf-8"}, headers)
end 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 def test_header_value_leading_and_trailing_whitespace_is_stripped
parser = HTTPTools::Parser.new parser = HTTPTools::Parser.new
headers = nil headers = nil
Expand Down Expand Up @@ -1203,6 +1223,29 @@ def test_trailer_value_separated_by_newline
assert_equal({"X-Test" => "one two"}, trailer) assert_equal({"X-Test" => "one two"}, trailer)
end 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 def test_trailer_value_leading_and_trailing_whitespace_is_stripped
parser = HTTPTools::Parser.new parser = HTTPTools::Parser.new
trailer = nil trailer = nil
Expand Down

0 comments on commit 62791f1

Please sign in to comment.