# HG changeset patch # User Kim Alvefur # Date 1701447079 -3600 # Node ID 977d92aff5630f9a82268a6155bb2ec5e6d23084 # Parent 81ae5e12550f3a821e2825c19c9353431029fd5c# Parent db30ffbf20903a54b0fabb24c024cfd755dbf8da Merge 0.12->trunk diff -r 81ae5e12550f -r 977d92aff563 net/http/parser.lua --- a/net/http/parser.lua Thu Nov 30 18:45:05 2023 +0100 +++ b/net/http/parser.lua Fri Dec 01 17:11:19 2023 +0100 @@ -59,7 +59,13 @@ while buffer:length() > 0 do if state == nil then -- read request local index = buffer:sub(1, headlimit):find("\r\n\r\n", nil, true); - if not index then return; end -- not enough data + if not index then + if buffer:length() > headlimit then + return error_cb("header-too-large"); + end + -- not enough data + return; + end -- FIXME was reason_phrase meant to be passed on somewhere? local method, path, httpversion, status_code, reason_phrase; -- luacheck: ignore reason_phrase local first_line; diff -r 81ae5e12550f -r 977d92aff563 spec/net_http_parser_spec.lua --- a/spec/net_http_parser_spec.lua Thu Nov 30 18:45:05 2023 +0100 +++ b/spec/net_http_parser_spec.lua Fri Dec 01 17:11:19 2023 +0100 @@ -167,6 +167,33 @@ } ); end); + + it("should reject very large request heads", function() + local finished = false; + local success_cb = spy.new(function() + finished = true; + end) + local error_cb = spy.new(function() + finished = true; + end) + local parser = http_parser.new(success_cb, error_cb, "server", function() + return { head_size_limit = 1024; body_size_limit = 1024; buffer_size_limit = 2048 }; + end) + parser:feed("GET / HTTP/1.1\r\n"); + for i = 1, 64 do -- * header line > buffer_size_limit + parser:feed(string.format("Header-%04d: Yet-AnotherValue\r\n", i)); + if finished then + -- should hit an error around half-way + break + end + end + if not finished then + parser:feed("\r\n") + end + assert.spy(success_cb).was_called(0); + assert.spy(error_cb).was_called(1); + assert.spy(error_cb).was_called_with("header-too-large"); + end) end); it("should handle large chunked responses", function ()