From bfb840fe8e158efdc47ff94e6f99499f86a97136 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Sun, 15 May 2016 16:21:36 -0400 Subject: [PATCH] Fix parser off by one accessing buffer bug: This fixed a bug where in some cases the parser could dereference past the end of the caller provided buffer. The unit test is improved to allocate memory in separate pieces for the split-buffer matrix test, to give address-sanitizer more to work with. --- include/beast/http/impl/basic_parser_v1.ipp | 6 ++++-- test/http/basic_parser_v1.cpp | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/include/beast/http/impl/basic_parser_v1.ipp b/include/beast/http/impl/basic_parser_v1.ipp index 2b40d3e4..4e6a6776 100644 --- a/include/beast/http/impl/basic_parser_v1.ipp +++ b/include/beast/http/impl/basic_parser_v1.ipp @@ -463,8 +463,9 @@ write(boost::asio::const_buffer const& buffer, error_code& ec) case s_header_field: { - for(; p != end; ch = *++p) + for(; p != end; ++p) { + ch = *p; auto c = to_field_char(ch); if(! c) break; @@ -660,8 +661,9 @@ write(boost::asio::const_buffer const& buffer, error_code& ec) case s_header_value_text: { - for(; p != end; ch = *++p) + for(; p != end; ++p) { + ch = *p; if(ch == '\r') { if(cb(nullptr)) diff --git a/test/http/basic_parser_v1.cpp b/test/http/basic_parser_v1.cpp index 99355e01..bef3d4cd 100644 --- a/test/http/basic_parser_v1.cpp +++ b/test/http/basic_parser_v1.cpp @@ -532,6 +532,7 @@ public: void testInvalidMatrix() { using boost::asio::buffer; + using boost::asio::buffer_copy; std::string s; for(std::size_t n = 0;; ++n) @@ -549,15 +550,24 @@ public: s[n] = 0; for(std::size_t m = 1; m < len - 1; ++m) { + // Use separately allocated buffers so + // address sanitizer has something to chew on. + // + std::unique_ptr p1(new char[m]); + std::unique_ptr p2(new char[len - m]); + auto const b1 = buffer(p1.get(), m); + auto const b2 = buffer(p2.get(), len - m); + buffer_copy(b1, buffer(s.data(), m)); + buffer_copy(b2, buffer(s.data() + m, len - m)); null_parser p; error_code ec; - p.write(buffer(s.data(), m), ec); + p.write(b1, ec); if(ec) { pass(); continue; } - p.write(buffer(s.data() + m, len - m), ec); + p.write(b2, ec); expect(ec); } }