2017-07-20 08:01:46 -07:00
|
|
|
|
//
|
2019-02-21 07:00:31 -08:00
|
|
|
|
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
|
2017-07-20 08:01:46 -07:00
|
|
|
|
//
|
|
|
|
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
|
|
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
|
|
//
|
2017-07-20 13:40:34 -07:00
|
|
|
|
// Official repository: https://github.com/boostorg/beast
|
|
|
|
|
|
//
|
2017-07-20 08:01:46 -07:00
|
|
|
|
|
|
|
|
|
|
// Test that header file is self-contained.
|
2017-07-20 13:40:34 -07:00
|
|
|
|
#include <boost/beast/websocket/detail/utf8_checker.hpp>
|
2017-07-20 08:01:46 -07:00
|
|
|
|
|
2017-09-15 12:52:45 -07:00
|
|
|
|
#include <boost/beast/core/buffers_suffix.hpp>
|
2017-07-20 13:40:34 -07:00
|
|
|
|
#include <boost/beast/core/multi_buffer.hpp>
|
2018-11-11 14:07:55 -08:00
|
|
|
|
#include <boost/beast/_experimental/unit_test/suite.hpp>
|
2017-07-20 08:01:46 -07:00
|
|
|
|
#include <array>
|
|
|
|
|
|
|
2017-07-20 13:40:34 -07:00
|
|
|
|
namespace boost {
|
2017-07-20 08:01:46 -07:00
|
|
|
|
namespace beast {
|
|
|
|
|
|
namespace websocket {
|
2016-04-30 10:29:39 -04:00
|
|
|
|
namespace detail {
|
2017-07-20 08:01:46 -07:00
|
|
|
|
|
2016-05-06 19:14:17 -04:00
|
|
|
|
class utf8_checker_test : public beast::unit_test::suite
|
2017-07-20 08:01:46 -07:00
|
|
|
|
{
|
|
|
|
|
|
public:
|
|
|
|
|
|
void
|
|
|
|
|
|
testOneByteSequence()
|
|
|
|
|
|
{
|
2017-08-30 17:39:24 -07:00
|
|
|
|
// valid single-char code points
|
|
|
|
|
|
for(unsigned char c = 0; c < 128; ++c)
|
|
|
|
|
|
{
|
2017-10-25 23:24:19 -07:00
|
|
|
|
utf8_checker u;
|
|
|
|
|
|
BEAST_EXPECT(u.write(&c, 1));
|
|
|
|
|
|
BEAST_EXPECT(u.finish());
|
2017-08-30 17:39:24 -07:00
|
|
|
|
}
|
2017-07-20 08:01:46 -07:00
|
|
|
|
|
2017-08-30 17:39:24 -07:00
|
|
|
|
// invalid lead bytes
|
|
|
|
|
|
for(unsigned char c = 128; c < 192; ++c)
|
|
|
|
|
|
{
|
2017-10-25 23:24:19 -07:00
|
|
|
|
utf8_checker u;
|
|
|
|
|
|
BEAST_EXPECT(! u.write(&c, 1));
|
2017-08-30 17:39:24 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// two byte sequences
|
|
|
|
|
|
for(unsigned char c = 192; c < 224; ++c)
|
|
|
|
|
|
{
|
2017-10-25 23:24:19 -07:00
|
|
|
|
// fail fast
|
|
|
|
|
|
utf8_checker u;
|
2017-11-07 16:37:09 -05:00
|
|
|
|
if (c < 194)
|
|
|
|
|
|
BEAST_EXPECT(! u.write(&c, 1));
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
BEAST_EXPECT(u.write(&c, 1));
|
|
|
|
|
|
BEAST_EXPECT(! u.finish());
|
|
|
|
|
|
}
|
2017-08-30 17:39:24 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// three byte sequences
|
|
|
|
|
|
for(unsigned char c = 224; c < 240; ++c)
|
|
|
|
|
|
{
|
2017-10-25 23:24:19 -07:00
|
|
|
|
utf8_checker u;
|
2018-09-18 14:38:15 -06:00
|
|
|
|
BEAST_EXPECT(u.write(&c, 1));
|
|
|
|
|
|
BEAST_EXPECT(! u.finish());
|
2017-08-30 17:39:24 -07:00
|
|
|
|
}
|
2016-10-28 19:43:30 -04:00
|
|
|
|
|
2017-08-30 17:39:24 -07:00
|
|
|
|
// four byte sequences
|
2017-11-07 16:37:09 -05:00
|
|
|
|
for(unsigned char c = 240; c < 245; ++c)
|
2017-08-30 17:39:24 -07:00
|
|
|
|
{
|
2017-11-07 16:37:09 -05:00
|
|
|
|
// fail fast
|
2017-10-25 23:24:19 -07:00
|
|
|
|
utf8_checker u;
|
2018-09-18 14:38:15 -06:00
|
|
|
|
BEAST_EXPECT(u.write(&c, 1));
|
|
|
|
|
|
BEAST_EXPECT(! u.finish());
|
2017-08-30 17:39:24 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// invalid lead bytes
|
2017-11-07 16:37:09 -05:00
|
|
|
|
for(unsigned char c = 245; c; ++c)
|
2017-08-30 17:39:24 -07:00
|
|
|
|
{
|
2017-10-25 23:24:19 -07:00
|
|
|
|
utf8_checker u;
|
|
|
|
|
|
BEAST_EXPECT(! u.write(&c, 1));
|
2017-08-30 17:39:24 -07:00
|
|
|
|
}
|
2017-07-20 08:01:46 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
testTwoByteSequence()
|
|
|
|
|
|
{
|
2017-10-25 23:24:19 -07:00
|
|
|
|
// Autobahn 6.18.1
|
|
|
|
|
|
{
|
|
|
|
|
|
utf8_checker u;
|
2018-11-30 14:58:38 -08:00
|
|
|
|
BEAST_EXPECT(! u.write(net::buffer("\xc1\xbf", 2)));
|
2017-10-25 23:24:19 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
utf8_checker u;
|
2017-07-20 08:01:46 -07:00
|
|
|
|
std::uint8_t buf[2];
|
2017-11-07 16:37:09 -05:00
|
|
|
|
// First byte valid range 194-223
|
|
|
|
|
|
for(auto i : {194, 223})
|
2017-07-20 08:01:46 -07:00
|
|
|
|
{
|
|
|
|
|
|
buf[0] = static_cast<std::uint8_t>(i);
|
|
|
|
|
|
|
2017-11-07 16:37:09 -05:00
|
|
|
|
// Second byte valid range 128-191
|
|
|
|
|
|
for(auto j : {128, 191})
|
2017-07-20 08:01:46 -07:00
|
|
|
|
{
|
|
|
|
|
|
buf[1] = static_cast<std::uint8_t>(j);
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(u.write(buf, 2));
|
|
|
|
|
|
BEAST_EXPECT(u.finish());
|
2017-07-20 08:01:46 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-07 16:37:09 -05:00
|
|
|
|
// Second byte invalid range 0-127
|
|
|
|
|
|
for(auto j : {0, 127})
|
2017-07-20 08:01:46 -07:00
|
|
|
|
{
|
|
|
|
|
|
buf[1] = static_cast<std::uint8_t>(j);
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(! u.write(buf, 2));
|
|
|
|
|
|
u.reset();
|
2017-07-20 08:01:46 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-07 16:37:09 -05:00
|
|
|
|
// Second byte invalid range 192-255
|
|
|
|
|
|
for(auto j : {192, 255})
|
2017-07-20 08:01:46 -07:00
|
|
|
|
{
|
|
|
|
|
|
buf[1] = static_cast<std::uint8_t>(j);
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(! u.write(buf, 2));
|
|
|
|
|
|
u.reset();
|
2017-07-20 08:01:46 -07:00
|
|
|
|
}
|
2016-10-28 19:43:30 -04:00
|
|
|
|
|
|
|
|
|
|
// Segmented sequence second byte invalid
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(u.write(buf, 1));
|
|
|
|
|
|
BEAST_EXPECT(! u.write(&buf[1], 1));
|
|
|
|
|
|
u.reset();
|
2017-07-20 08:01:46 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
testThreeByteSequence()
|
|
|
|
|
|
{
|
2017-10-25 23:24:19 -07:00
|
|
|
|
{
|
|
|
|
|
|
utf8_checker u;
|
2018-11-30 14:58:38 -08:00
|
|
|
|
BEAST_EXPECT(u.write(net::buffer("\xef\xbf\xbf", 3)));
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(u.finish());
|
|
|
|
|
|
}
|
|
|
|
|
|
utf8_checker u;
|
2017-07-20 08:01:46 -07:00
|
|
|
|
std::uint8_t buf[3];
|
2017-11-07 16:37:09 -05:00
|
|
|
|
// First byte valid range 224-239
|
|
|
|
|
|
for(auto i : {224, 239})
|
2017-07-20 08:01:46 -07:00
|
|
|
|
{
|
|
|
|
|
|
buf[0] = static_cast<std::uint8_t>(i);
|
|
|
|
|
|
|
2017-11-07 16:37:09 -05:00
|
|
|
|
// Second byte valid range 128-191 or 160-191 or 128-159
|
2017-07-20 08:01:46 -07:00
|
|
|
|
std::int32_t const b = (i == 224 ? 160 : 128);
|
|
|
|
|
|
std::int32_t const e = (i == 237 ? 159 : 191);
|
2017-11-07 16:37:09 -05:00
|
|
|
|
for(auto j : {b, e})
|
2017-07-20 08:01:46 -07:00
|
|
|
|
{
|
|
|
|
|
|
buf[1] = static_cast<std::uint8_t>(j);
|
|
|
|
|
|
|
2017-11-07 16:37:09 -05:00
|
|
|
|
// Third byte valid range 128-191
|
|
|
|
|
|
for(auto k : {128, 191})
|
2017-07-20 08:01:46 -07:00
|
|
|
|
{
|
|
|
|
|
|
buf[2] = static_cast<std::uint8_t>(k);
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(u.write(buf, 3));
|
|
|
|
|
|
BEAST_EXPECT(u.finish());
|
2016-11-14 17:21:42 -05:00
|
|
|
|
// Segmented sequence
|
2018-09-18 14:38:15 -06:00
|
|
|
|
if (i == 224)
|
|
|
|
|
|
{
|
|
|
|
|
|
BEAST_EXPECT(u.write(buf, 1));
|
|
|
|
|
|
BEAST_EXPECT(!u.finish());
|
|
|
|
|
|
}
|
2017-11-07 16:37:09 -05:00
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
BEAST_EXPECT(u.write(buf, 1));
|
|
|
|
|
|
BEAST_EXPECT(u.write(&buf[1], 2));
|
|
|
|
|
|
}
|
2017-10-25 23:24:19 -07:00
|
|
|
|
u.reset();
|
2016-11-14 17:21:42 -05:00
|
|
|
|
// Segmented sequence
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(u.write(buf, 2));
|
|
|
|
|
|
BEAST_EXPECT(u.write(&buf[2], 1));
|
|
|
|
|
|
u.reset();
|
2016-11-14 17:21:42 -05:00
|
|
|
|
|
|
|
|
|
|
if (i == 224)
|
|
|
|
|
|
{
|
2017-11-07 16:37:09 -05:00
|
|
|
|
// Second byte invalid range 0-159
|
|
|
|
|
|
for (auto l : {0, 159})
|
2016-11-14 17:21:42 -05:00
|
|
|
|
{
|
|
|
|
|
|
buf[1] = static_cast<std::uint8_t>(l);
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(! u.write(buf, 3));
|
|
|
|
|
|
u.reset();
|
2017-11-07 16:37:09 -05:00
|
|
|
|
// Segmented sequence second byte invalid
|
|
|
|
|
|
BEAST_EXPECT(!u.write(buf, 2));
|
|
|
|
|
|
u.reset();
|
|
|
|
|
|
}
|
|
|
|
|
|
// Second byte invalid range 192-255
|
|
|
|
|
|
for(auto l : {192, 255})
|
|
|
|
|
|
{
|
|
|
|
|
|
buf[1] = static_cast<std::uint8_t>(l);
|
|
|
|
|
|
BEAST_EXPECT(! u.write(buf, 3));
|
|
|
|
|
|
u.reset();
|
|
|
|
|
|
// Segmented sequence second byte invalid
|
|
|
|
|
|
BEAST_EXPECT(!u.write(buf, 2));
|
|
|
|
|
|
u.reset();
|
2016-11-14 17:21:42 -05:00
|
|
|
|
}
|
|
|
|
|
|
buf[1] = static_cast<std::uint8_t>(j);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (i == 237)
|
|
|
|
|
|
{
|
2017-11-07 16:37:09 -05:00
|
|
|
|
// Second byte invalid range 0-127
|
|
|
|
|
|
for(auto l : {0, 127})
|
2016-11-14 17:21:42 -05:00
|
|
|
|
{
|
|
|
|
|
|
buf[1] = static_cast<std::uint8_t>(l);
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(! u.write(buf, 3));
|
|
|
|
|
|
u.reset();
|
2017-11-07 16:37:09 -05:00
|
|
|
|
// Segmented sequence second byte invalid
|
|
|
|
|
|
BEAST_EXPECT(!u.write(buf, 2));
|
|
|
|
|
|
u.reset();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Second byte invalid range 160-255
|
|
|
|
|
|
for(auto l : {160, 255})
|
|
|
|
|
|
{
|
|
|
|
|
|
buf[1] = static_cast<std::uint8_t>(l);
|
|
|
|
|
|
BEAST_EXPECT(! u.write(buf, 3));
|
|
|
|
|
|
u.reset();
|
|
|
|
|
|
// Segmented sequence second byte invalid
|
|
|
|
|
|
BEAST_EXPECT(! u.write(buf, 2));
|
|
|
|
|
|
u.reset();
|
2016-11-14 17:21:42 -05:00
|
|
|
|
}
|
|
|
|
|
|
buf[1] = static_cast<std::uint8_t>(j);
|
|
|
|
|
|
}
|
2017-07-20 08:01:46 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-07 16:37:09 -05:00
|
|
|
|
// Third byte invalid range 0-127
|
|
|
|
|
|
for(auto k : {0, 127})
|
2017-07-20 08:01:46 -07:00
|
|
|
|
{
|
|
|
|
|
|
buf[2] = static_cast<std::uint8_t>(k);
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(! u.write(buf, 3));
|
|
|
|
|
|
u.reset();
|
2017-07-20 08:01:46 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-07 16:37:09 -05:00
|
|
|
|
// Third byte invalid range 192-255
|
|
|
|
|
|
for(auto k : {192, 255})
|
2017-07-20 08:01:46 -07:00
|
|
|
|
{
|
|
|
|
|
|
buf[2] = static_cast<std::uint8_t>(k);
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(! u.write(buf, 3));
|
|
|
|
|
|
u.reset();
|
2017-07-20 08:01:46 -07:00
|
|
|
|
}
|
2016-10-28 19:43:30 -04:00
|
|
|
|
|
|
|
|
|
|
// Segmented sequence third byte invalid
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(u.write(buf, 2));
|
|
|
|
|
|
BEAST_EXPECT(! u.write(&buf[2], 1));
|
|
|
|
|
|
u.reset();
|
2017-07-20 08:01:46 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-07 16:37:09 -05:00
|
|
|
|
// Second byte invalid range 0-127 or 0-159
|
|
|
|
|
|
for(auto j : {0, b - 1})
|
2017-07-20 08:01:46 -07:00
|
|
|
|
{
|
|
|
|
|
|
buf[1] = static_cast<std::uint8_t>(j);
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(! u.write(buf, 3));
|
|
|
|
|
|
u.reset();
|
2017-07-20 08:01:46 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-07 16:37:09 -05:00
|
|
|
|
// Second byte invalid range 160-255 or 192-255
|
|
|
|
|
|
for(auto j : {e + 1, 255})
|
2017-07-20 08:01:46 -07:00
|
|
|
|
{
|
|
|
|
|
|
buf[1] = static_cast<std::uint8_t>(j);
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(! u.write(buf, 3));
|
|
|
|
|
|
u.reset();
|
2017-07-20 08:01:46 -07:00
|
|
|
|
}
|
2016-10-28 19:43:30 -04:00
|
|
|
|
|
|
|
|
|
|
// Segmented sequence second byte invalid
|
2018-09-18 14:38:15 -06:00
|
|
|
|
if (i == 224) {
|
|
|
|
|
|
BEAST_EXPECT(u.write(buf, 1));
|
|
|
|
|
|
BEAST_EXPECT(!u.finish());
|
|
|
|
|
|
}
|
2017-11-07 16:37:09 -05:00
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
BEAST_EXPECT(u.write(buf, 1));
|
|
|
|
|
|
BEAST_EXPECT(!u.write(&buf[1], 1));
|
|
|
|
|
|
}
|
2017-10-25 23:24:19 -07:00
|
|
|
|
u.reset();
|
2017-07-20 08:01:46 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
testFourByteSequence()
|
|
|
|
|
|
{
|
2018-11-30 14:58:38 -08:00
|
|
|
|
using net::const_buffer;
|
2017-10-25 23:24:19 -07:00
|
|
|
|
utf8_checker u;
|
2017-07-20 08:01:46 -07:00
|
|
|
|
std::uint8_t buf[4];
|
2017-11-07 16:37:09 -05:00
|
|
|
|
// First byte valid range 240-244
|
|
|
|
|
|
for(auto i : {240, 244})
|
2017-07-20 08:01:46 -07:00
|
|
|
|
{
|
|
|
|
|
|
buf[0] = static_cast<std::uint8_t>(i);
|
|
|
|
|
|
|
|
|
|
|
|
std::int32_t const b = (i == 240 ? 144 : 128);
|
|
|
|
|
|
std::int32_t const e = (i == 244 ? 143 : 191);
|
2016-08-26 08:01:44 -04:00
|
|
|
|
for(auto j = b; j <= e; ++j)
|
2017-07-20 08:01:46 -07:00
|
|
|
|
{
|
|
|
|
|
|
buf[1] = static_cast<std::uint8_t>(j);
|
|
|
|
|
|
|
2017-11-07 16:37:09 -05:00
|
|
|
|
// Second byte valid range 144-191 or 128-191 or 128-143
|
|
|
|
|
|
for(auto k : {128, 191})
|
2017-07-20 08:01:46 -07:00
|
|
|
|
{
|
|
|
|
|
|
buf[2] = static_cast<std::uint8_t>(k);
|
|
|
|
|
|
|
2017-11-07 16:37:09 -05:00
|
|
|
|
// Third byte valid range 128-191
|
2017-08-01 14:00:51 -04:00
|
|
|
|
for(auto n : {128, 191})
|
2017-07-20 08:01:46 -07:00
|
|
|
|
{
|
|
|
|
|
|
// Fourth byte valid range 128-191
|
|
|
|
|
|
buf[3] = static_cast<std::uint8_t>(n);
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(u.write(buf, 4));
|
|
|
|
|
|
BEAST_EXPECT(u.finish());
|
2016-11-14 17:21:42 -05:00
|
|
|
|
// Segmented sequence
|
2018-09-18 14:38:15 -06:00
|
|
|
|
BEAST_EXPECT(u.write(buf, 1));
|
|
|
|
|
|
BEAST_EXPECT(u.write(&buf[1], 3));
|
2017-10-25 23:24:19 -07:00
|
|
|
|
u.reset();
|
2016-11-14 17:21:42 -05:00
|
|
|
|
// Segmented sequence
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(u.write(buf, 2));
|
|
|
|
|
|
BEAST_EXPECT(u.write(&buf[2], 2));
|
|
|
|
|
|
u.reset();
|
2016-11-14 17:21:42 -05:00
|
|
|
|
// Segmented sequence
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(u.write(buf, 3));
|
|
|
|
|
|
BEAST_EXPECT(u.write(&buf[3], 1));
|
|
|
|
|
|
u.reset();
|
2016-11-14 17:21:42 -05:00
|
|
|
|
|
|
|
|
|
|
if (i == 240)
|
|
|
|
|
|
{
|
2017-11-07 16:37:09 -05:00
|
|
|
|
// Second byte invalid range 0-143
|
|
|
|
|
|
for(auto r : {0, 143})
|
|
|
|
|
|
{
|
|
|
|
|
|
buf[1] = static_cast<std::uint8_t>(r);
|
|
|
|
|
|
BEAST_EXPECT(! u.write(buf, 4));
|
|
|
|
|
|
u.reset();
|
|
|
|
|
|
// Segmented sequence second byte invalid
|
|
|
|
|
|
BEAST_EXPECT(! u.write(buf, 2));
|
|
|
|
|
|
u.reset();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Second byte invalid range 192-255
|
|
|
|
|
|
for(auto r : {192, 255})
|
2016-11-14 17:21:42 -05:00
|
|
|
|
{
|
2017-08-01 14:00:51 -04:00
|
|
|
|
buf[1] = static_cast<std::uint8_t>(r);
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(! u.write(buf, 4));
|
|
|
|
|
|
u.reset();
|
2017-11-07 16:37:09 -05:00
|
|
|
|
// Segmented sequence second byte invalid
|
|
|
|
|
|
BEAST_EXPECT(!u.write(buf, 2));
|
|
|
|
|
|
u.reset();
|
2016-11-14 17:21:42 -05:00
|
|
|
|
}
|
|
|
|
|
|
buf[1] = static_cast<std::uint8_t>(j);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (i == 244)
|
|
|
|
|
|
{
|
2017-11-07 16:37:09 -05:00
|
|
|
|
// Second byte invalid range 0-127
|
|
|
|
|
|
for(auto r : {0, 127})
|
|
|
|
|
|
{
|
|
|
|
|
|
buf[1] = static_cast<std::uint8_t>(r);
|
|
|
|
|
|
BEAST_EXPECT(! u.write(buf, 4));
|
|
|
|
|
|
u.reset();
|
|
|
|
|
|
// Segmented sequence second byte invalid
|
|
|
|
|
|
BEAST_EXPECT(! u.write(buf, 2));
|
|
|
|
|
|
u.reset();
|
|
|
|
|
|
}
|
|
|
|
|
|
// Second byte invalid range 144-255
|
|
|
|
|
|
for(auto r : {144, 255})
|
2016-11-14 17:21:42 -05:00
|
|
|
|
{
|
2017-08-01 14:00:51 -04:00
|
|
|
|
buf[1] = static_cast<std::uint8_t>(r);
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(! u.write(buf, 4));
|
|
|
|
|
|
u.reset();
|
2017-08-01 14:00:51 -04:00
|
|
|
|
// Segmented sequence second byte invalid
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(! u.write(buf, 2));
|
|
|
|
|
|
u.reset();
|
2016-11-14 17:21:42 -05:00
|
|
|
|
}
|
|
|
|
|
|
buf[1] = static_cast<std::uint8_t>(j);
|
|
|
|
|
|
}
|
2017-07-20 08:01:46 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-08-01 14:00:51 -04:00
|
|
|
|
// Fourth byte invalid ranges 0-127, 192-255
|
|
|
|
|
|
for(auto r : {0, 127, 192, 255})
|
2017-07-20 08:01:46 -07:00
|
|
|
|
{
|
2017-08-01 14:00:51 -04:00
|
|
|
|
buf[3] = static_cast<std::uint8_t>(r);
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(! u.write(buf, 4));
|
|
|
|
|
|
u.reset();
|
2017-07-20 08:01:46 -07:00
|
|
|
|
}
|
2016-10-28 19:43:30 -04:00
|
|
|
|
|
|
|
|
|
|
// Segmented sequence fourth byte invalid
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(u.write(buf, 3));
|
|
|
|
|
|
BEAST_EXPECT(! u.write(&buf[3], 1));
|
|
|
|
|
|
u.reset();
|
2017-07-20 08:01:46 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-08-01 14:00:51 -04:00
|
|
|
|
// Third byte invalid ranges 0-127, 192-255
|
|
|
|
|
|
for(auto r : {0, 127, 192, 255})
|
2017-07-20 08:01:46 -07:00
|
|
|
|
{
|
2017-08-01 14:00:51 -04:00
|
|
|
|
buf[2] = static_cast<std::uint8_t>(r);
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(! u.write(buf, 4));
|
|
|
|
|
|
u.reset();
|
2017-07-20 08:01:46 -07:00
|
|
|
|
}
|
2016-10-28 19:43:30 -04:00
|
|
|
|
|
|
|
|
|
|
// Segmented sequence third byte invalid
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(u.write(buf, 2));
|
|
|
|
|
|
BEAST_EXPECT(! u.write(&buf[2], 1));
|
|
|
|
|
|
u.reset();
|
2017-07-20 08:01:46 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-08-01 14:00:51 -04:00
|
|
|
|
// Second byte invalid range 0-127 or 0-143
|
|
|
|
|
|
for(auto r : {0, b - 1})
|
2017-07-20 08:01:46 -07:00
|
|
|
|
{
|
2017-08-01 14:00:51 -04:00
|
|
|
|
buf[1] = static_cast<std::uint8_t>(r);
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(! u.write(buf, 4));
|
|
|
|
|
|
u.reset();
|
2017-07-20 08:01:46 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-08-01 14:00:51 -04:00
|
|
|
|
// Second byte invalid range 144-255 or 192-255
|
|
|
|
|
|
for(auto r : {e + 1, 255})
|
2017-07-20 08:01:46 -07:00
|
|
|
|
{
|
2017-08-01 14:00:51 -04:00
|
|
|
|
buf[1] = static_cast<std::uint8_t>(r);
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(! u.write(buf, 4));
|
|
|
|
|
|
u.reset();
|
2017-07-20 08:01:46 -07:00
|
|
|
|
}
|
2016-10-28 19:43:30 -04:00
|
|
|
|
|
|
|
|
|
|
// Segmented sequence second byte invalid
|
2018-09-18 14:38:15 -06:00
|
|
|
|
BEAST_EXPECT(u.write(buf, 1));
|
|
|
|
|
|
BEAST_EXPECT(! u.write(&buf[1], 1));
|
|
|
|
|
|
|
2017-10-25 23:24:19 -07:00
|
|
|
|
u.reset();
|
2017-07-20 08:01:46 -07:00
|
|
|
|
}
|
2016-11-14 17:21:42 -05:00
|
|
|
|
|
2017-08-01 14:00:51 -04:00
|
|
|
|
// First byte invalid range 245-255
|
|
|
|
|
|
for(auto r : {245, 255})
|
2016-11-14 17:21:42 -05:00
|
|
|
|
{
|
2017-08-01 14:00:51 -04:00
|
|
|
|
buf[0] = static_cast<std::uint8_t>(r);
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(! u.write(buf, 4));
|
|
|
|
|
|
u.reset();
|
2016-11-14 17:21:42 -05:00
|
|
|
|
}
|
2017-07-20 08:01:46 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
testWithStreamBuffer()
|
|
|
|
|
|
{
|
|
|
|
|
|
{
|
2016-04-30 10:29:39 -04:00
|
|
|
|
// Valid UTF8 encoded text
|
|
|
|
|
|
std::vector<std::vector<std::uint8_t>> const data{{
|
|
|
|
|
|
0x48,0x65,0x69,0x7A,0xC3,0xB6,0x6C,0x72,0xC3,0xBC,0x63,0x6B,
|
|
|
|
|
|
0x73,0x74,0x6F,0xC3,0x9F,0x61,0x62,0x64,0xC3,0xA4,0x6D,0x70,
|
|
|
|
|
|
0x66,0x75,0x6E,0x67
|
|
|
|
|
|
}, {
|
|
|
|
|
|
0xCE,0x93,0xCE,0xB1,0xCE,0xB6,0xCE,0xAD,0xCE,0xB5,0xCF,0x82,
|
|
|
|
|
|
0x20,0xCE,0xBA,0xCE,0xB1,0xE1,0xBD,0xB6,0x20,0xCE,0xBC,0xCF,
|
|
|
|
|
|
0x85,0xCF,0x81,0xCF,0x84,0xCE,0xB9,0xE1,0xBD,0xB2,0xCF,0x82,
|
|
|
|
|
|
0x20,0xCE,0xB4,0xE1,0xBD,0xB2,0xCE,0xBD,0x20,0xCE,0xB8,0xE1,
|
|
|
|
|
|
0xBD,0xB0,0x20,0xCE,0xB2,0xCF,0x81,0xE1,0xBF,0xB6,0x20,0xCF,
|
|
|
|
|
|
0x80,0xCE,0xB9,0xE1,0xBD,0xB0,0x20,0xCF,0x83,0xCF,0x84,0xE1,
|
|
|
|
|
|
0xBD,0xB8,0x20,0xCF,0x87,0xCF,0x81,0xCF,0x85,0xCF,0x83,0xCE,
|
|
|
|
|
|
0xB1,0xCF,0x86,0xE1,0xBD,0xB6,0x20,0xCE,0xBE,0xCE,0xAD,0xCF,
|
|
|
|
|
|
0x86,0xCF,0x89,0xCF,0x84,0xCE,0xBF
|
|
|
|
|
|
}, {
|
|
|
|
|
|
0xC3,0x81,0x72,0x76,0xC3,0xAD,0x7A,0x74,0xC5,0xB1,0x72,0xC5,
|
|
|
|
|
|
0x91,0x20,0x74,0xC3,0xBC,0x6B,0xC3,0xB6,0x72,0x66,0xC3,0xBA,
|
|
|
|
|
|
0x72,0xC3,0xB3,0x67,0xC3,0xA9,0x70
|
2016-10-28 19:43:30 -04:00
|
|
|
|
}, {
|
|
|
|
|
|
240, 144, 128, 128
|
2016-04-30 10:29:39 -04:00
|
|
|
|
}
|
|
|
|
|
|
};
|
2017-10-25 23:24:19 -07:00
|
|
|
|
utf8_checker u;
|
2016-04-30 10:29:39 -04:00
|
|
|
|
for(auto const& s : data)
|
|
|
|
|
|
{
|
2016-10-28 19:43:30 -04:00
|
|
|
|
static std::size_t constexpr size = 3;
|
2016-04-30 10:29:39 -04:00
|
|
|
|
std::size_t n = s.size();
|
2017-09-15 12:52:45 -07:00
|
|
|
|
buffers_suffix<
|
2018-11-30 14:58:38 -08:00
|
|
|
|
net::const_buffer> cb{
|
|
|
|
|
|
net::const_buffer(s.data(), n)};
|
2017-06-08 11:07:37 -07:00
|
|
|
|
multi_buffer b;
|
2016-04-30 10:29:39 -04:00
|
|
|
|
while(n)
|
|
|
|
|
|
{
|
2016-11-08 13:03:20 -05:00
|
|
|
|
auto const amount = (std::min)(n, size);
|
2018-11-30 14:58:38 -08:00
|
|
|
|
b.commit(net::buffer_copy(
|
2017-09-07 07:39:52 -07:00
|
|
|
|
b.prepare(amount), cb));
|
2016-04-30 10:29:39 -04:00
|
|
|
|
cb.consume(amount);
|
|
|
|
|
|
n -= amount;
|
|
|
|
|
|
}
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(u.write(b.data()));
|
|
|
|
|
|
BEAST_EXPECT(u.finish());
|
2016-04-30 10:29:39 -04:00
|
|
|
|
}
|
2017-07-20 08:01:46 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-08-30 17:39:24 -07:00
|
|
|
|
void
|
|
|
|
|
|
testBranches()
|
|
|
|
|
|
{
|
|
|
|
|
|
// switch to slow loop from alignment loop
|
|
|
|
|
|
{
|
|
|
|
|
|
char buf[32];
|
|
|
|
|
|
for(unsigned i = 0; i < sizeof(buf); i += 2)
|
|
|
|
|
|
{
|
2017-11-07 16:37:09 -05:00
|
|
|
|
buf[i ] = '\xc2';
|
2017-08-30 17:39:24 -07:00
|
|
|
|
buf[i+1] = '\x80';
|
|
|
|
|
|
}
|
|
|
|
|
|
auto p = reinterpret_cast<char const*>(sizeof(std::size_t) * (
|
|
|
|
|
|
(std::uintptr_t(buf) + sizeof(std::size_t) - 1) /
|
|
|
|
|
|
sizeof(std::size_t))) + 2;
|
2017-10-25 23:24:19 -07:00
|
|
|
|
utf8_checker u;
|
|
|
|
|
|
BEAST_EXPECT(u.write(
|
2017-08-30 17:39:24 -07:00
|
|
|
|
reinterpret_cast<std::uint8_t const*>(p),
|
|
|
|
|
|
sizeof(buf)-(p-buf)));
|
2017-10-25 23:24:19 -07:00
|
|
|
|
BEAST_EXPECT(u.finish());
|
2017-08-30 17:39:24 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// invalid code point in the last dword of a fast run
|
|
|
|
|
|
{
|
|
|
|
|
|
char buf[20];
|
|
|
|
|
|
auto p = reinterpret_cast<char*>(sizeof(std::size_t) * (
|
|
|
|
|
|
(std::uintptr_t(buf) + sizeof(std::size_t) - 1) /
|
|
|
|
|
|
sizeof(std::size_t)));
|
|
|
|
|
|
BOOST_ASSERT(p + 12 <= buf + sizeof(buf));
|
|
|
|
|
|
auto const in = p;
|
|
|
|
|
|
*p++ = '*'; *p++ = '*'; *p++ = '*'; *p++ = '*';
|
|
|
|
|
|
*p++ = '*'; *p++ = '*'; *p++ = '*'; *p++ = '*';
|
|
|
|
|
|
p[0] = '\x80'; // invalid
|
|
|
|
|
|
p[1] = '*';
|
|
|
|
|
|
p[2] = '*';
|
|
|
|
|
|
p[3] = '*';
|
2017-10-25 23:24:19 -07:00
|
|
|
|
utf8_checker u;
|
|
|
|
|
|
BEAST_EXPECT(! u.write(reinterpret_cast<
|
2017-08-30 17:39:24 -07:00
|
|
|
|
std::uint8_t const*>(in), 12));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-18 14:38:15 -06:00
|
|
|
|
void
|
|
|
|
|
|
AutodeskTests()
|
|
|
|
|
|
{
|
|
|
|
|
|
std::vector<std::vector<std::uint8_t>> const data{
|
|
|
|
|
|
{ 's','t','a','r','t', 0xE0 },
|
|
|
|
|
|
{ 0xA6, 0x81, 'e','n','d' } };
|
|
|
|
|
|
utf8_checker u;
|
|
|
|
|
|
for(auto const& s : data)
|
|
|
|
|
|
{
|
|
|
|
|
|
std::size_t n = s.size();
|
2018-11-30 14:58:38 -08:00
|
|
|
|
buffers_suffix<net::const_buffer> cb{net::const_buffer(s.data(), n)};
|
2018-09-18 14:38:15 -06:00
|
|
|
|
multi_buffer b;
|
|
|
|
|
|
while(n)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto const amount = (std::min)(n, std::size_t(3)/*size*/);
|
2018-11-30 14:58:38 -08:00
|
|
|
|
b.commit(net::buffer_copy(b.prepare(amount), cb));
|
2018-09-18 14:38:15 -06:00
|
|
|
|
cb.consume(amount);
|
|
|
|
|
|
n -= amount;
|
|
|
|
|
|
}
|
|
|
|
|
|
BEAST_EXPECT(u.write(b.data()));
|
|
|
|
|
|
}
|
|
|
|
|
|
BEAST_EXPECT(u.finish());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
AutobahnTest(std::vector<std::vector<std::uint8_t>>&& data, std::vector<bool> result)
|
|
|
|
|
|
{
|
|
|
|
|
|
BEAST_EXPECT(data.size() == result.size());
|
|
|
|
|
|
utf8_checker u;
|
|
|
|
|
|
for(std::size_t i = 0; i < data.size(); ++i)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto const& s = data[i];
|
|
|
|
|
|
|
|
|
|
|
|
std::size_t n = s.size();
|
2018-11-30 14:58:38 -08:00
|
|
|
|
buffers_suffix<net::const_buffer> cb{net::const_buffer(s.data(), n)};
|
2018-09-18 14:38:15 -06:00
|
|
|
|
multi_buffer b;
|
|
|
|
|
|
while(n)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto const amount = (std::min)(n, std::size_t(3)/*size*/);
|
2018-11-30 14:58:38 -08:00
|
|
|
|
b.commit(net::buffer_copy(b.prepare(amount), cb));
|
2018-09-18 14:38:15 -06:00
|
|
|
|
cb.consume(amount);
|
|
|
|
|
|
n -= amount;
|
|
|
|
|
|
}
|
|
|
|
|
|
BEAST_EXPECT(u.write(b.data()) == result[i]);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-08-30 17:39:24 -07:00
|
|
|
|
void
|
|
|
|
|
|
run() override
|
2017-07-20 08:01:46 -07:00
|
|
|
|
{
|
|
|
|
|
|
testOneByteSequence();
|
|
|
|
|
|
testTwoByteSequence();
|
|
|
|
|
|
testThreeByteSequence();
|
|
|
|
|
|
testFourByteSequence();
|
|
|
|
|
|
testWithStreamBuffer();
|
2017-08-30 17:39:24 -07:00
|
|
|
|
testBranches();
|
2018-09-18 14:38:15 -06:00
|
|
|
|
AutodeskTests();
|
|
|
|
|
|
// 6.4.2
|
|
|
|
|
|
AutobahnTest(std::vector<std::vector<std::uint8_t>>{
|
|
|
|
|
|
{ 0xCE, 0xBA, 0xE1, 0xBD, 0xB9, 0xCF, 0x83, 0xCE, 0xBC, 0xCE, 0xB5, 0xF4 },
|
|
|
|
|
|
{ 0x90 }, { 0x80, 0x80, 0x65, 0x64, 0x69, 0x74, 0x65, 0x64 } },
|
|
|
|
|
|
{ true, false, false});
|
|
|
|
|
|
// 6.4.4
|
|
|
|
|
|
AutobahnTest(std::vector<std::vector<std::uint8_t>>{
|
|
|
|
|
|
{ 0xCE, 0xBA, 0xE1, 0xBD, 0xB9, 0xCF, 0x83, 0xCE, 0xBC, 0xCE, 0xB5, 0xF4 },
|
|
|
|
|
|
{ 0x90 } },
|
|
|
|
|
|
{ true, false });
|
2017-07-20 08:01:46 -07:00
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2017-11-07 16:37:09 -05:00
|
|
|
|
BEAST_DEFINE_TESTSUITE(beast,websocket,utf8_checker);
|
2017-07-20 08:01:46 -07:00
|
|
|
|
|
2016-04-30 10:29:39 -04:00
|
|
|
|
} // detail
|
2017-07-20 08:01:46 -07:00
|
|
|
|
} // websocket
|
|
|
|
|
|
} // beast
|
2017-07-20 13:40:34 -07:00
|
|
|
|
} // boost
|