forked from boostorg/beast
Don't allocate memory to handle obs-fold
This commit is contained in:
@@ -1,3 +1,9 @@
|
|||||||
|
Version 55:
|
||||||
|
|
||||||
|
* Don't allocate memory to handle obs-fold
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
Version 54:
|
Version 54:
|
||||||
|
|
||||||
* static_buffer coverage
|
* static_buffer coverage
|
||||||
|
@@ -60,6 +60,9 @@ namespace http {
|
|||||||
|
|
||||||
@tparam Derived The derived class type. This is part of the
|
@tparam Derived The derived class type. This is part of the
|
||||||
Curiously Recurring Template Pattern interface.
|
Curiously Recurring Template Pattern interface.
|
||||||
|
|
||||||
|
@note If the parser encounters a field value with obs-fold
|
||||||
|
longer than 4 kilobytes in length, an error is generated.
|
||||||
*/
|
*/
|
||||||
template<bool isRequest, class Derived>
|
template<bool isRequest, class Derived>
|
||||||
class basic_parser
|
class basic_parser
|
||||||
@@ -68,6 +71,9 @@ class basic_parser
|
|||||||
template<bool OtherIsRequest, class OtherDerived>
|
template<bool OtherIsRequest, class OtherDerived>
|
||||||
friend class basic_parser;
|
friend class basic_parser;
|
||||||
|
|
||||||
|
// limit on the size of the obs-fold buffer
|
||||||
|
static std::size_t constexpr max_obs_fold = 4096;
|
||||||
|
|
||||||
// Message will be complete after reading header
|
// Message will be complete after reading header
|
||||||
static unsigned constexpr flagSkipBody = 1<< 0;
|
static unsigned constexpr flagSkipBody = 1<< 0;
|
||||||
|
|
||||||
|
@@ -115,7 +115,10 @@ enum class error
|
|||||||
bad_transfer_encoding,
|
bad_transfer_encoding,
|
||||||
|
|
||||||
/// The chunk syntax is invalid.
|
/// The chunk syntax is invalid.
|
||||||
bad_chunk
|
bad_chunk,
|
||||||
|
|
||||||
|
/// An obs-fold exceeded an internal limit.
|
||||||
|
bad_obs_fold
|
||||||
};
|
};
|
||||||
|
|
||||||
} // http
|
} // http
|
||||||
|
@@ -40,12 +40,11 @@ namespace http {
|
|||||||
as a `std::multiset`; there will be a separate value for each occurrence
|
as a `std::multiset`; there will be a separate value for each occurrence
|
||||||
of the field name.
|
of the field name.
|
||||||
|
|
||||||
@note Meets the requirements of @b Fields
|
Meets the requirements of @b Fields
|
||||||
*/
|
*/
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
class basic_fields
|
class basic_fields
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
using off_t = std::uint16_t;
|
using off_t = std::uint16_t;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#ifndef BEAST_HTTP_IMPL_BASIC_PARSER_IPP
|
#ifndef BEAST_HTTP_IMPL_BASIC_PARSER_IPP
|
||||||
#define BEAST_HTTP_IMPL_BASIC_PARSER_IPP
|
#define BEAST_HTTP_IMPL_BASIC_PARSER_IPP
|
||||||
|
|
||||||
|
#include <beast/core/static_string.hpp>
|
||||||
#include <beast/core/type_traits.hpp>
|
#include <beast/core/type_traits.hpp>
|
||||||
#include <beast/core/detail/ci_char_traits.hpp>
|
#include <beast/core/detail/ci_char_traits.hpp>
|
||||||
#include <beast/core/detail/clamp.hpp>
|
#include <beast/core/detail/clamp.hpp>
|
||||||
@@ -701,25 +702,34 @@ parse_fields(char const*& p,
|
|||||||
if(ec)
|
if(ec)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::string s;
|
// https://stackoverflow.com/questions/686217/maximum-on-http-header-values
|
||||||
if(p != term)
|
static_string<max_obs_fold> s;
|
||||||
|
try
|
||||||
{
|
{
|
||||||
s.append(p, term - 2);
|
if(p != term)
|
||||||
p = term;
|
|
||||||
for(;;)
|
|
||||||
{
|
{
|
||||||
if(*p != ' ' && *p != '\t')
|
s.append(p, term - 2);
|
||||||
break;
|
|
||||||
s.push_back(' ');
|
|
||||||
detail::skip_ows(p, term - 2);
|
|
||||||
term = find_eol(p, last, ec);
|
|
||||||
if(ec)
|
|
||||||
return;
|
|
||||||
if(p != term - 2)
|
|
||||||
s.append(p, term - 2);
|
|
||||||
p = term;
|
p = term;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
if(*p != ' ' && *p != '\t')
|
||||||
|
break;
|
||||||
|
s.push_back(' ');
|
||||||
|
detail::skip_ows(p, term - 2);
|
||||||
|
term = find_eol(p, last, ec);
|
||||||
|
if(ec)
|
||||||
|
return;
|
||||||
|
if(p != term - 2)
|
||||||
|
s.append(p, term - 2);
|
||||||
|
p = term;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch(std::length_error const&)
|
||||||
|
{
|
||||||
|
ec = error::bad_obs_fold;
|
||||||
|
return;
|
||||||
|
}
|
||||||
auto const f = string_to_field(name);
|
auto const f = string_to_field(name);
|
||||||
string_view const value{s.data(), s.size()};
|
string_view const value{s.data(), s.size()};
|
||||||
do_field(f, value, ec);
|
do_field(f, value, ec);
|
||||||
|
@@ -56,6 +56,7 @@ public:
|
|||||||
case error::bad_content_length: return "bad Content-Length";
|
case error::bad_content_length: return "bad Content-Length";
|
||||||
case error::bad_transfer_encoding: return "bad Transfer-Encoding";
|
case error::bad_transfer_encoding: return "bad Transfer-Encoding";
|
||||||
case error::bad_chunk: return "bad chunk";
|
case error::bad_chunk: return "bad chunk";
|
||||||
|
case error::bad_obs_fold: return "bad obs-fold";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user