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.
This commit is contained in:
Vinnie Falco
2016-05-15 16:21:36 -04:00
parent 236f9598ce
commit bfb840fe8e
2 changed files with 16 additions and 4 deletions

View File

@@ -463,8 +463,9 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
case s_header_field: case s_header_field:
{ {
for(; p != end; ch = *++p) for(; p != end; ++p)
{ {
ch = *p;
auto c = to_field_char(ch); auto c = to_field_char(ch);
if(! c) if(! c)
break; break;
@@ -660,8 +661,9 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
case s_header_value_text: case s_header_value_text:
{ {
for(; p != end; ch = *++p) for(; p != end; ++p)
{ {
ch = *p;
if(ch == '\r') if(ch == '\r')
{ {
if(cb(nullptr)) if(cb(nullptr))

View File

@@ -532,6 +532,7 @@ public:
void testInvalidMatrix() void testInvalidMatrix()
{ {
using boost::asio::buffer; using boost::asio::buffer;
using boost::asio::buffer_copy;
std::string s; std::string s;
for(std::size_t n = 0;; ++n) for(std::size_t n = 0;; ++n)
@@ -549,15 +550,24 @@ public:
s[n] = 0; s[n] = 0;
for(std::size_t m = 1; m < len - 1; ++m) 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<char[]> p1(new char[m]);
std::unique_ptr<char[]> 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<true> p; null_parser<true> p;
error_code ec; error_code ec;
p.write(buffer(s.data(), m), ec); p.write(b1, ec);
if(ec) if(ec)
{ {
pass(); pass();
continue; continue;
} }
p.write(buffer(s.data() + m, len - m), ec); p.write(b2, ec);
expect(ec); expect(ec);
} }
} }