basic_parser: apply header_limit_ to trailer headers

This commit is contained in:
Mohammad Nejati
2024-08-22 00:22:16 +03:30
committed by Mohammad Nejati
parent f181fbf6e4
commit a620d4175a
6 changed files with 86 additions and 138 deletions
+62 -96
View File
@@ -164,6 +164,20 @@ loop:
parse_chunk_header(p, n, ec);
if(ec)
goto done;
BOOST_ASSERT(! skip_);
if(state_ != state::trailer_fields)
break;
n = static_cast<std::size_t>(p1 - p);
BOOST_FALLTHROUGH;
case state::trailer_fields:
parse_fields(p, n, ec);
if(ec)
goto done;
this->on_finish_impl(ec);
if(ec)
goto done;
state_ = state::complete;
break;
case state::chunk_body:
@@ -564,7 +578,7 @@ parse_body_to_eof(char const*& p,
template<bool isRequest>
void
basic_parser<isRequest>::
parse_chunk_header(char const*& p0,
parse_chunk_header(char const*& in,
std::size_t n, error_code& ec)
{
/*
@@ -581,101 +595,52 @@ parse_chunk_header(char const*& p0,
chunk-ext-val = token / quoted-string
*/
auto p = p0;
auto p = in;
auto const pend = p + n;
char const* eol;
if(! (f_ & flagFinalChunk))
if(n < skip_ + 2)
{
if(n < skip_ + 2)
{
BOOST_BEAST_ASSIGN_EC(ec, error::need_more);
return;
}
if(f_ & flagExpectCRLF)
{
// Treat the last CRLF in a chunk as
// part of the next chunk, so p can
// be parsed in one call instead of two.
if(! parse_crlf(p))
{
BOOST_BEAST_ASSIGN_EC(ec, error::bad_chunk);
return;
}
}
eol = find_eol(p0 + skip_, pend, ec);
if(ec)
return;
if(! eol)
{
BOOST_BEAST_ASSIGN_EC(ec, error::need_more);
skip_ = n - 1;
return;
}
skip_ = static_cast<
std::size_t>(eol - 2 - p0);
std::uint64_t size;
if(! parse_hex(p, size))
BOOST_BEAST_ASSIGN_EC(ec, error::need_more);
return;
}
if(f_ & flagExpectCRLF)
{
// Treat the last CRLF in a chunk as
// part of the next chunk, so p can
// be parsed in one call instead of two.
if(! parse_crlf(p))
{
BOOST_BEAST_ASSIGN_EC(ec, error::bad_chunk);
return;
}
if(size != 0)
}
auto const eol = find_eol(p + skip_, pend, ec);
if(ec)
return;
if(! eol)
{
BOOST_BEAST_ASSIGN_EC(ec, error::need_more);
if(p != pend)
skip_ = pend - p - 1;
return;
}
skip_ = static_cast<std::size_t>(eol - p - 2);
std::uint64_t size;
if(! parse_hex(p, size))
{
BOOST_BEAST_ASSIGN_EC(ec, error::bad_chunk);
return;
}
if (body_limit_.has_value())
{
if (size > *body_limit_)
{
if (body_limit_.has_value())
{
if (size > *body_limit_)
{
BOOST_BEAST_ASSIGN_EC(ec, error::body_limit);
return;
}
*body_limit_ -= size;
}
auto const start = p;
parse_chunk_extensions(p, pend, ec);
if(ec)
return;
if(p != eol -2 )
{
BOOST_BEAST_ASSIGN_EC(ec, error::bad_chunk_extension);
return;
}
auto const ext = make_string(start, p);
this->on_chunk_header_impl(size, ext, ec);
if(ec)
return;
len_ = size;
skip_ = 2;
p0 = eol;
f_ |= flagExpectCRLF;
state_ = state::chunk_body;
BOOST_BEAST_ASSIGN_EC(ec, error::body_limit);
return;
}
f_ |= flagFinalChunk;
}
else
{
BOOST_ASSERT(n >= 3);
if(f_ & flagExpectCRLF)
{
BOOST_ASSERT(n >= 5);
BOOST_VERIFY(parse_crlf(p));
}
std::uint64_t size;
BOOST_VERIFY(parse_hex(p, size));
eol = find_eol(p, pend, ec);
BOOST_ASSERT(! ec);
}
auto eom = find_eom(p0 + skip_, pend);
if(! eom)
{
BOOST_ASSERT(n >= 3);
skip_ = n - 3;
BOOST_BEAST_ASSIGN_EC(ec, error::need_more);
return;
*body_limit_ -= size;
}
auto const start = p;
@@ -688,20 +653,21 @@ parse_chunk_header(char const*& p0,
return;
}
auto const ext = make_string(start, p);
this->on_chunk_header_impl(0, ext, ec);
this->on_chunk_header_impl(size, ext, ec);
if(ec)
return;
p = eol;
parse_fields(p, static_cast<std::size_t>(eom - p), ec);
if(ec)
return;
BOOST_ASSERT(p == eom);
p0 = eom;
this->on_finish_impl(ec);
if(ec)
len_ = size;
skip_ = 0;
in = eol;
f_ |= flagExpectCRLF;
if(size != 0)
{
state_ = state::chunk_body;
return;
state_ = state::complete;
}
state_ = state::trailer_fields;
header_limit_ += 2; // for the final chunk's CRLF
}
template<bool isRequest>