From c49bee78db977db35f0eeb014e87f061b4ebf1eb Mon Sep 17 00:00:00 2001 From: Miguel Portilla Date: Mon, 14 Nov 2016 17:21:42 -0500 Subject: [PATCH] Increase utf8 checker code coverage --- .../beast/websocket/detail/utf8_checker.hpp | 10 +- test/websocket/utf8_checker.cpp | 93 +++++++++++++++++++ 2 files changed, 97 insertions(+), 6 deletions(-) diff --git a/include/beast/websocket/detail/utf8_checker.hpp b/include/beast/websocket/detail/utf8_checker.hpp index b7ffe26a..6f3eaf0a 100644 --- a/include/beast/websocket/detail/utf8_checker.hpp +++ b/include/beast/websocket/detail/utf8_checker.hpp @@ -153,9 +153,8 @@ utf8_checker_t<_>::write(std::uint8_t const* in, std::size_t size) } if ((in[0] & 0x60) == 0x40) { - if ((in[0] & 0xfe) == 0xc0 || - (in[1] & 0xc0) != 0x80) - return false; + if ((in[1] & 0xc0) != 0x80) + return false; in += 2; return true; } @@ -200,9 +199,8 @@ utf8_checker_t<_>::write(std::uint8_t const* in, std::size_t size) if ((have_[0] & 0xf8) == 0xf0) { auto const size = p_ - have_; - if (have_[0] > 244 || - (size > 2 && (have_[2] & 0xc0) != 0x80)) - return false; + if (size > 2 && (have_[2] & 0xc0) != 0x80) + return false; if (size > 1 && ((have_[1] & 0xc0) != 0x80 || (have_[0] == 240 && have_[1] < 144) || diff --git a/test/websocket/utf8_checker.cpp b/test/websocket/utf8_checker.cpp index 90d5d697..3e4055df 100644 --- a/test/websocket/utf8_checker.cpp +++ b/test/websocket/utf8_checker.cpp @@ -115,6 +115,47 @@ public: buf[2] = static_cast(k); BEAST_EXPECT(utf8.write(buf, 3)); BEAST_EXPECT(utf8.finish()); + // Segmented sequence + BEAST_EXPECT(utf8.write(buf, 1)); + BEAST_EXPECT(utf8.write(&buf[1], 2)); + utf8.reset(); + // Segmented sequence + BEAST_EXPECT(utf8.write(buf, 2)); + BEAST_EXPECT(utf8.write(&buf[2], 1)); + utf8.reset(); + + if (i == 224) + { + for (auto l = 0; l < b; ++l) + { + // Second byte invalid range 0-127 or 0-159 + buf[1] = static_cast(l); + BEAST_EXPECT(! utf8.write(buf, 3)); + if (l > 127) + { + // Segmented sequence second byte invalid + BEAST_EXPECT(! utf8.write(buf, 2)); + utf8.reset(); + } + } + buf[1] = static_cast(j); + } + else if (i == 237) + { + for (auto l = e + 1; l <= 255; ++l) + { + // Second byte invalid range 160-255 or 192-255 + buf[1] = static_cast(l); + BEAST_EXPECT(!utf8.write(buf, 3)); + if (l > 159) + { + // Segmented sequence second byte invalid + BEAST_EXPECT(! utf8.write(buf, 2)); + utf8.reset(); + } + } + buf[1] = static_cast(j); + } } for(auto k = 0; k <= 127; ++k) @@ -187,6 +228,51 @@ public: buf[3] = static_cast(n); BEAST_EXPECT(utf8.write(const_buffers_1{buf, 4})); BEAST_EXPECT(utf8.finish()); + // Segmented sequence + BEAST_EXPECT(utf8.write(buf, 1)); + BEAST_EXPECT(utf8.write(&buf[1], 3)); + utf8.reset(); + // Segmented sequence + BEAST_EXPECT(utf8.write(buf, 2)); + BEAST_EXPECT(utf8.write(&buf[2], 2)); + utf8.reset(); + // Segmented sequence + BEAST_EXPECT(utf8.write(buf, 3)); + BEAST_EXPECT(utf8.write(&buf[3], 1)); + utf8.reset(); + + if (i == 240) + { + for (auto l = 0; l < b; ++l) + { + // Second byte invalid range 0-127 or 0-143 + buf[1] = static_cast(l); + BEAST_EXPECT(! utf8.write(buf, 4)); + if (l > 127) + { + // Segmented sequence second byte invalid + BEAST_EXPECT(! utf8.write(buf, 2)); + utf8.reset(); + } + } + buf[1] = static_cast(j); + } + else if (i == 244) + { + for (auto l = e + 1; l <= 255; ++l) + { + // Second byte invalid range 144-255 or 192-255 + buf[1] = static_cast(l); + BEAST_EXPECT(! utf8.write(buf, 4)); + if (l > 143) + { + // Segmented sequence second byte invalid + BEAST_EXPECT(! utf8.write(buf, 2)); + utf8.reset(); + } + } + buf[1] = static_cast(j); + } } for(auto n = 0; n <= 127; ++n) @@ -248,6 +334,13 @@ public: BEAST_EXPECT(! utf8.write(&buf[1], 1)); utf8.reset(); } + + for (auto i = 245; i <= 255; ++i) + { + // First byte invalid range 245-255 + buf[0] = static_cast(i); + BEAST_EXPECT(! utf8.write(buf, 4)); + } } void