Skip to content

Commit

Permalink
basic_parser returns error::header_limit ealier
Browse files Browse the repository at this point in the history
  • Loading branch information
ashtum committed Aug 20, 2024
1 parent 0040621 commit b7e42d2
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 79 deletions.
19 changes: 12 additions & 7 deletions include/boost/beast/http/basic_parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -642,23 +642,28 @@ class basic_parser
error_code& ec);

void
maybe_need_more(
char const* p, std::size_t n,
error_code& ec);
inner_parse_start_line(
char const*& p, char const* last,
error_code& ec, std::true_type);

void
parse_start_line(
inner_parse_start_line(
char const*& p, char const* last,
error_code& ec, std::true_type);
error_code& ec, std::false_type);

void
parse_start_line(
char const*& p, std::size_t n,
error_code& ec);

void
inner_parse_fields(
char const*& p, char const* last,
error_code& ec, std::false_type);
error_code& ec);

void
parse_fields(
char const*& p, char const* last,
char const*& p, std::size_t n,
error_code& ec);

void
Expand Down
111 changes: 39 additions & 72 deletions include/boost/beast/http/impl/basic_parser.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -112,26 +112,9 @@ loop:

case state::start_line:
{
maybe_need_more(p, n, ec);
parse_start_line(p, n, ec);
if(ec)
goto done;
parse_start_line(p, p + (std::min<std::size_t>)(
header_limit_, n), ec, is_request{});
if(ec)
{
if(ec == error::need_more)
{
if(n >= header_limit_)
{
BOOST_BEAST_ASSIGN_EC(ec, error::header_limit);
goto done;
}
if(p + 3 <= p1)
skip_ = static_cast<
std::size_t>(p1 - p - 3);
}
goto done;
}
BOOST_ASSERT(! is_done());
n = static_cast<std::size_t>(p1 - p);
if(p >= p1)
Expand All @@ -143,26 +126,9 @@ loop:
}

case state::fields:
maybe_need_more(p, n, ec);
if(ec)
goto done;
parse_fields(p, p + (std::min<std::size_t>)(
header_limit_, n), ec);
parse_fields(p, n, ec);
if(ec)
{
if(ec == error::need_more)
{
if(n >= header_limit_)
{
BOOST_BEAST_ASSIGN_EC(ec, error::header_limit);
goto done;
}
if(p + 3 <= p1)
skip_ = static_cast<
std::size_t>(p1 - p - 3);
}
goto done;
}
finish_header(ec, is_request{});
if(ec)
goto done;
Expand Down Expand Up @@ -262,39 +228,7 @@ put_eof(error_code& ec)
template<bool isRequest>
void
basic_parser<isRequest>::
maybe_need_more(
char const* p, std::size_t n,
error_code& ec)
{
if(skip_ == 0)
return;
if( n > header_limit_)
n = header_limit_;
if(n < skip_ + 4)
{
BOOST_BEAST_ASSIGN_EC(ec, error::need_more);
return;
}
auto const term =
find_eom(p + skip_, p + n);
if(! term)
{
skip_ = n - 3;
if(skip_ + 4 > header_limit_)
{
BOOST_BEAST_ASSIGN_EC(ec, error::header_limit);
return;
}
BOOST_BEAST_ASSIGN_EC(ec, error::need_more);
return;
}
skip_ = 0;
}

template<bool isRequest>
void
basic_parser<isRequest>::
parse_start_line(
inner_parse_start_line(
char const*& in, char const* last,
error_code& ec, std::true_type)
{
Expand Down Expand Up @@ -351,7 +285,7 @@ parse_start_line(
template<bool isRequest>
void
basic_parser<isRequest>::
parse_start_line(
inner_parse_start_line(
char const*& in, char const* last,
error_code& ec, std::false_type)
{
Expand Down Expand Up @@ -409,7 +343,24 @@ parse_start_line(
template<bool isRequest>
void
basic_parser<isRequest>::
parse_fields(char const*& in,
parse_start_line(
char const*& in, std::size_t n, error_code& ec)
{
auto const p0 = in;

inner_parse_start_line(in, in + (std::min<std::size_t>)
(n, header_limit_), ec, is_request{});
if(ec == error::need_more && n >= header_limit_)
{
BOOST_BEAST_ASSIGN_EC(ec, error::header_limit);
}
header_limit_ -= static_cast<std::uint32_t>(in - p0);
}

template<bool isRequest>
void
basic_parser<isRequest>::
inner_parse_fields(char const*& in,
char const* last, error_code& ec)
{
string_view name;
Expand Down Expand Up @@ -447,6 +398,22 @@ parse_fields(char const*& in,
}
}

template<bool isRequest>
void
basic_parser<isRequest>::
parse_fields(char const*& in, std::size_t n, error_code& ec)
{
auto const p0 = in;

inner_parse_fields(in, in + (std::min<std::size_t>)
(n, header_limit_), ec);
if(ec == error::need_more && n >= header_limit_)
{
BOOST_BEAST_ASSIGN_EC(ec, error::header_limit);
}
header_limit_ -= static_cast<std::uint32_t>(in - p0);
}

template<bool isRequest>
void
basic_parser<isRequest>::
Expand Down Expand Up @@ -736,7 +703,7 @@ parse_chunk_header(char const*& p0,
if(ec)
return;
p = eol;
parse_fields(p, eom, ec);
parse_fields(p, static_cast<std::size_t>(eom - p), ec);
if(ec)
return;
BOOST_ASSERT(p == eom);
Expand Down
16 changes: 16 additions & 0 deletions test/beast/http/basic_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,22 @@ class basic_parser_test : public beast::unit_test::suite
p.put(b.data(), ec);
BEAST_EXPECTS(ec == error::header_limit, ec.message());
}
{
multi_buffer b;
ostream(b) <<
"POST / HTTP/1.1\r\n";
error_code ec;
test_parser<true> p;
p.header_limit(18);
p.eager(true);
b.consume(p.put(b.data(), ec));
BEAST_EXPECTS(ec == error::need_more, ec.message());
ostream(b) <<
"field: value\r\n";
b.consume(p.put(b.data(), ec));
BEAST_EXPECT(! p.is_done());
BEAST_EXPECTS(ec == error::header_limit, ec.message());
}
{
multi_buffer b;
ostream(b) <<
Expand Down

0 comments on commit b7e42d2

Please sign in to comment.