diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c1502fd..4da4c6cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ Version 66: * Make consuming_buffers smaller * Fix costly potential value-init in parser * Fix unused parameter warning +* Handle bad_alloc in parser -------------------------------------------------------------------------------- diff --git a/include/beast/http/error.hpp b/include/beast/http/error.hpp index 4240ed94..16f43979 100644 --- a/include/beast/http/error.hpp +++ b/include/beast/http/error.hpp @@ -80,6 +80,13 @@ enum class error */ buffer_overflow, + /** A memory allocation failed. + + When basic_fields throws std::bad_alloc, it is + converted into this error by @ref parser. + */ + bad_alloc, + // // (parser errors) // diff --git a/include/beast/http/impl/error.ipp b/include/beast/http/impl/error.ipp index 9e2a4be7..d4df0da1 100644 --- a/include/beast/http/impl/error.ipp +++ b/include/beast/http/impl/error.ipp @@ -44,6 +44,7 @@ public: case error::unexpected_body: return "unexpected body"; case error::need_buffer: return "need buffer"; case error::buffer_overflow: return "buffer overflow"; + case error::bad_alloc: return "bad alloc"; case error::bad_line_ending: return "bad line ending"; case error::bad_method: return "bad method"; case error::bad_path: return "bad path"; diff --git a/include/beast/http/parser.hpp b/include/beast/http/parser.hpp index e6b9481d..132046d8 100644 --- a/include/beast/http/parser.hpp +++ b/include/beast/http/parser.hpp @@ -198,12 +198,19 @@ private: on_request(verb method, string_view method_str, string_view target, int version, error_code& ec) { - ec.assign(0, ec.category()); - m_.target(target); - if(method != verb::unknown) - m_.method(method); - else - m_.method_string(method_str); + try + { + m_.target(target); + if(method != verb::unknown) + m_.method(method); + else + m_.method_string(method_str); + ec.assign(0, ec.category()); + } + catch(std::bad_alloc const&) + { + ec = error::bad_alloc; + } m_.version = version; } @@ -212,18 +219,32 @@ private: string_view reason, int version, error_code& ec) { - ec.assign(0, ec.category()); m_.result(code); m_.version = version; - m_.reason(reason); + try + { + m_.reason(reason); + ec.assign(0, ec.category()); + } + catch(std::bad_alloc const&) + { + ec = error::bad_alloc; + } } void on_field(field name, string_view name_string, string_view value, error_code& ec) { - ec.assign(0, ec.category()); - m_.insert(name, name_string, value); + try + { + m_.insert(name, name_string, value); + ec.assign(0, ec.category()); + } + catch(std::bad_alloc const&) + { + ec = error::bad_alloc; + } } void diff --git a/test/http/error.cpp b/test/http/error.cpp index 7f9abe6f..9e6c2aee 100644 --- a/test/http/error.cpp +++ b/test/http/error.cpp @@ -42,6 +42,7 @@ public: check("beast.http", error::unexpected_body); check("beast.http", error::need_buffer); check("beast.http", error::buffer_overflow); + check("beast.http", error::bad_alloc); check("beast.http", error::bad_line_ending); check("beast.http", error::bad_method);