Don't allocate memory to handle obs-fold

This commit is contained in:
Vinnie Falco
2017-06-11 09:58:57 -07:00
parent add95d6ef6
commit 87c6e69d9f
6 changed files with 42 additions and 17 deletions

View File

@ -1,3 +1,9 @@
Version 55:
* Don't allocate memory to handle obs-fold
--------------------------------------------------------------------------------
Version 54:
* static_buffer coverage

View File

@ -60,6 +60,9 @@ namespace http {
@tparam Derived The derived class type. This is part of the
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>
class basic_parser
@ -68,6 +71,9 @@ class basic_parser
template<bool OtherIsRequest, class OtherDerived>
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
static unsigned constexpr flagSkipBody = 1<< 0;

View File

@ -115,7 +115,10 @@ enum class error
bad_transfer_encoding,
/// The chunk syntax is invalid.
bad_chunk
bad_chunk,
/// An obs-fold exceeded an internal limit.
bad_obs_fold
};
} // http

View File

@ -40,12 +40,11 @@ namespace http {
as a `std::multiset`; there will be a separate value for each occurrence
of the field name.
@note Meets the requirements of @b Fields
Meets the requirements of @b Fields
*/
template<class Allocator>
class basic_fields
{
private:
using off_t = std::uint16_t;
public:

View File

@ -8,6 +8,7 @@
#ifndef 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/detail/ci_char_traits.hpp>
#include <beast/core/detail/clamp.hpp>
@ -701,25 +702,34 @@ parse_fields(char const*& p,
if(ec)
return;
}
std::string s;
if(p != term)
// https://stackoverflow.com/questions/686217/maximum-on-http-header-values
static_string<max_obs_fold> s;
try
{
s.append(p, term - 2);
p = term;
for(;;)
if(p != term)
{
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);
s.append(p, term - 2);
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);
string_view const value{s.data(), s.size()};
do_field(f, value, ec);

View File

@ -56,6 +56,7 @@ public:
case error::bad_content_length: return "bad Content-Length";
case error::bad_transfer_encoding: return "bad Transfer-Encoding";
case error::bad_chunk: return "bad chunk";
case error::bad_obs_fold: return "bad obs-fold";
}
}