]> git.proxmox.com Git - ceph.git/blob - ceph/src/Beast/test/websocket/utf8_checker.cpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / Beast / test / websocket / utf8_checker.cpp
1 //
2 // Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7
8 // Test that header file is self-contained.
9 #include <beast/websocket/detail/utf8_checker.hpp>
10
11 #include <beast/core/consuming_buffers.hpp>
12 #include <beast/core/streambuf.hpp>
13 #include <beast/unit_test/suite.hpp>
14 #include <array>
15
16 namespace beast {
17 namespace websocket {
18 namespace detail {
19
20 class utf8_checker_test : public beast::unit_test::suite
21 {
22 public:
23 void
24 testOneByteSequence()
25 {
26 utf8_checker utf8;
27 std::array<std::uint8_t, 256> buf =
28 ([]()
29 {
30 std::array<std::uint8_t, 256> values;
31 std::uint8_t i = 0;
32 for(auto& c : values)
33 c = i++;
34 return values;
35 })();
36
37 // Valid range 0-127
38 BEAST_EXPECT(utf8.write(buf.data(), 128));
39 BEAST_EXPECT(utf8.finish());
40
41 // Invalid range 128-193
42 for(auto it = std::next(buf.begin(), 128);
43 it != std::next(buf.begin(), 194); ++it)
44 BEAST_EXPECT(! utf8.write(&(*it), 1));
45
46 // Invalid range 245-255
47 for(auto it = std::next(buf.begin(), 245);
48 it != buf.end(); ++it)
49 BEAST_EXPECT(! utf8.write(&(*it), 1));
50
51 // Invalid sequence
52 std::fill(buf.begin(), buf.end(), 0xFF);
53 BEAST_EXPECT(! utf8.write(&buf.front(), buf.size()));
54 }
55
56 void
57 testTwoByteSequence()
58 {
59 utf8_checker utf8;
60 std::uint8_t buf[2];
61 for(auto i = 194; i <= 223; ++i)
62 {
63 // First byte valid range 194-223
64 buf[0] = static_cast<std::uint8_t>(i);
65
66 for(auto j = 128; j <= 191; ++j)
67 {
68 // Second byte valid range 128-191
69 buf[1] = static_cast<std::uint8_t>(j);
70 BEAST_EXPECT(utf8.write(buf, 2));
71 BEAST_EXPECT(utf8.finish());
72 }
73
74 for(auto j = 0; j <= 127; ++j)
75 {
76 // Second byte invalid range 0-127
77 buf[1] = static_cast<std::uint8_t>(j);
78 BEAST_EXPECT(! utf8.write(buf, 2));
79 }
80
81 for(auto j = 192; j <= 255; ++j)
82 {
83 // Second byte invalid range 192-255
84 buf[1] = static_cast<std::uint8_t>(j);
85 BEAST_EXPECT(! utf8.write(buf, 2));
86 }
87
88 // Segmented sequence second byte invalid
89 BEAST_EXPECT(utf8.write(buf, 1));
90 BEAST_EXPECT(! utf8.write(&buf[1], 1));
91 utf8.reset();
92 }
93 }
94
95 void
96 testThreeByteSequence()
97 {
98 utf8_checker utf8;
99 std::uint8_t buf[3];
100 for(auto i = 224; i <= 239; ++i)
101 {
102 // First byte valid range 224-239
103 buf[0] = static_cast<std::uint8_t>(i);
104
105 std::int32_t const b = (i == 224 ? 160 : 128);
106 std::int32_t const e = (i == 237 ? 159 : 191);
107 for(auto j = b; j <= e; ++j)
108 {
109 // Second byte valid range 128-191 or 160-191 or 128-159
110 buf[1] = static_cast<std::uint8_t>(j);
111
112 for(auto k = 128; k <= 191; ++k)
113 {
114 // Third byte valid range 128-191
115 buf[2] = static_cast<std::uint8_t>(k);
116 BEAST_EXPECT(utf8.write(buf, 3));
117 BEAST_EXPECT(utf8.finish());
118 // Segmented sequence
119 BEAST_EXPECT(utf8.write(buf, 1));
120 BEAST_EXPECT(utf8.write(&buf[1], 2));
121 utf8.reset();
122 // Segmented sequence
123 BEAST_EXPECT(utf8.write(buf, 2));
124 BEAST_EXPECT(utf8.write(&buf[2], 1));
125 utf8.reset();
126
127 if (i == 224)
128 {
129 for (auto l = 0; l < b; ++l)
130 {
131 // Second byte invalid range 0-127 or 0-159
132 buf[1] = static_cast<std::uint8_t>(l);
133 BEAST_EXPECT(! utf8.write(buf, 3));
134 if (l > 127)
135 {
136 // Segmented sequence second byte invalid
137 BEAST_EXPECT(! utf8.write(buf, 2));
138 utf8.reset();
139 }
140 }
141 buf[1] = static_cast<std::uint8_t>(j);
142 }
143 else if (i == 237)
144 {
145 for (auto l = e + 1; l <= 255; ++l)
146 {
147 // Second byte invalid range 160-255 or 192-255
148 buf[1] = static_cast<std::uint8_t>(l);
149 BEAST_EXPECT(!utf8.write(buf, 3));
150 if (l > 159)
151 {
152 // Segmented sequence second byte invalid
153 BEAST_EXPECT(! utf8.write(buf, 2));
154 utf8.reset();
155 }
156 }
157 buf[1] = static_cast<std::uint8_t>(j);
158 }
159 }
160
161 for(auto k = 0; k <= 127; ++k)
162 {
163 // Third byte invalid range 0-127
164 buf[2] = static_cast<std::uint8_t>(k);
165 BEAST_EXPECT(! utf8.write(buf, 3));
166 }
167
168 for(auto k = 192; k <= 255; ++k)
169 {
170 // Third byte invalid range 192-255
171 buf[2] = static_cast<std::uint8_t>(k);
172 BEAST_EXPECT(! utf8.write(buf, 3));
173 }
174
175 // Segmented sequence third byte invalid
176 BEAST_EXPECT(utf8.write(buf, 2));
177 BEAST_EXPECT(! utf8.write(&buf[2], 1));
178 utf8.reset();
179 }
180
181 for(auto j = 0; j < b; ++j)
182 {
183 // Second byte invalid range 0-127 or 0-159
184 buf[1] = static_cast<std::uint8_t>(j);
185 BEAST_EXPECT(! utf8.write(buf, 3));
186 }
187
188 for(auto j = e + 1; j <= 255; ++j)
189 {
190 // Second byte invalid range 160-255 or 192-255
191 buf[1] = static_cast<std::uint8_t>(j);
192 BEAST_EXPECT(! utf8.write(buf, 3));
193 }
194
195 // Segmented sequence second byte invalid
196 BEAST_EXPECT(utf8.write(buf, 1));
197 BEAST_EXPECT(! utf8.write(&buf[1], 1));
198 utf8.reset();
199 }
200 }
201
202 void
203 testFourByteSequence()
204 {
205 using boost::asio::const_buffers_1;
206 utf8_checker utf8;
207 std::uint8_t buf[4];
208 for(auto i = 240; i <= 244; ++i)
209 {
210 // First byte valid range 240-244
211 buf[0] = static_cast<std::uint8_t>(i);
212
213 std::int32_t const b = (i == 240 ? 144 : 128);
214 std::int32_t const e = (i == 244 ? 143 : 191);
215 for(auto j = b; j <= e; ++j)
216 {
217 // Second byte valid range 144-191 or 128-191 or 128-143
218 buf[1] = static_cast<std::uint8_t>(j);
219
220 for(auto k = 128; k <= 191; ++k)
221 {
222 // Third byte valid range 128-191
223 buf[2] = static_cast<std::uint8_t>(k);
224
225 for(auto n = 128; n <= 191; ++n)
226 {
227 // Fourth byte valid range 128-191
228 buf[3] = static_cast<std::uint8_t>(n);
229 BEAST_EXPECT(utf8.write(const_buffers_1{buf, 4}));
230 BEAST_EXPECT(utf8.finish());
231 // Segmented sequence
232 BEAST_EXPECT(utf8.write(buf, 1));
233 BEAST_EXPECT(utf8.write(&buf[1], 3));
234 utf8.reset();
235 // Segmented sequence
236 BEAST_EXPECT(utf8.write(buf, 2));
237 BEAST_EXPECT(utf8.write(&buf[2], 2));
238 utf8.reset();
239 // Segmented sequence
240 BEAST_EXPECT(utf8.write(buf, 3));
241 BEAST_EXPECT(utf8.write(&buf[3], 1));
242 utf8.reset();
243
244 if (i == 240)
245 {
246 for (auto l = 0; l < b; ++l)
247 {
248 // Second byte invalid range 0-127 or 0-143
249 buf[1] = static_cast<std::uint8_t>(l);
250 BEAST_EXPECT(! utf8.write(buf, 4));
251 if (l > 127)
252 {
253 // Segmented sequence second byte invalid
254 BEAST_EXPECT(! utf8.write(buf, 2));
255 utf8.reset();
256 }
257 }
258 buf[1] = static_cast<std::uint8_t>(j);
259 }
260 else if (i == 244)
261 {
262 for (auto l = e + 1; l <= 255; ++l)
263 {
264 // Second byte invalid range 144-255 or 192-255
265 buf[1] = static_cast<std::uint8_t>(l);
266 BEAST_EXPECT(! utf8.write(buf, 4));
267 if (l > 143)
268 {
269 // Segmented sequence second byte invalid
270 BEAST_EXPECT(! utf8.write(buf, 2));
271 utf8.reset();
272 }
273 }
274 buf[1] = static_cast<std::uint8_t>(j);
275 }
276 }
277
278 for(auto n = 0; n <= 127; ++n)
279 {
280 // Fourth byte invalid range 0-127
281 buf[3] = static_cast<std::uint8_t>(n);
282 BEAST_EXPECT(! utf8.write(const_buffers_1{buf, 4}));
283 }
284
285 for(auto n = 192; n <= 255; ++n)
286 {
287 // Fourth byte invalid range 192-255
288 buf[3] = static_cast<std::uint8_t>(n);
289 BEAST_EXPECT(! utf8.write(buf, 4));
290 }
291
292 // Segmented sequence fourth byte invalid
293 BEAST_EXPECT(utf8.write(buf, 3));
294 BEAST_EXPECT(! utf8.write(&buf[3], 1));
295 utf8.reset();
296 }
297
298 for(auto k = 0; k <= 127; ++k)
299 {
300 // Third byte invalid range 0-127
301 buf[2] = static_cast<std::uint8_t>(k);
302 BEAST_EXPECT(! utf8.write(buf, 4));
303 }
304
305 for(auto k = 192; k <= 255; ++k)
306 {
307 // Third byte invalid range 192-255
308 buf[2] = static_cast<std::uint8_t>(k);
309 BEAST_EXPECT(! utf8.write(buf, 4));
310 }
311
312 // Segmented sequence third byte invalid
313 BEAST_EXPECT(utf8.write(buf, 2));
314 BEAST_EXPECT(! utf8.write(&buf[2], 1));
315 utf8.reset();
316 }
317
318 for(auto j = 0; j < b; ++j)
319 {
320 // Second byte invalid range 0-127 or 0-143
321 buf[1] = static_cast<std::uint8_t>(j);
322 BEAST_EXPECT(! utf8.write(buf, 4));
323 }
324
325 for(auto j = e + 1; j <= 255; ++j)
326 {
327 // Second byte invalid range 144-255 or 192-255
328 buf[1] = static_cast<std::uint8_t>(j);
329 BEAST_EXPECT(! utf8.write(buf, 4));
330 }
331
332 // Segmented sequence second byte invalid
333 BEAST_EXPECT(utf8.write(buf, 1));
334 BEAST_EXPECT(! utf8.write(&buf[1], 1));
335 utf8.reset();
336 }
337
338 for (auto i = 245; i <= 255; ++i)
339 {
340 // First byte invalid range 245-255
341 buf[0] = static_cast<std::uint8_t>(i);
342 BEAST_EXPECT(! utf8.write(buf, 4));
343 }
344 }
345
346 void
347 testWithStreamBuffer()
348 {
349 using namespace boost::asio;
350 {
351 // Valid UTF8 encoded text
352 std::vector<std::vector<std::uint8_t>> const data{{
353 0x48,0x65,0x69,0x7A,0xC3,0xB6,0x6C,0x72,0xC3,0xBC,0x63,0x6B,
354 0x73,0x74,0x6F,0xC3,0x9F,0x61,0x62,0x64,0xC3,0xA4,0x6D,0x70,
355 0x66,0x75,0x6E,0x67
356 }, {
357 0xCE,0x93,0xCE,0xB1,0xCE,0xB6,0xCE,0xAD,0xCE,0xB5,0xCF,0x82,
358 0x20,0xCE,0xBA,0xCE,0xB1,0xE1,0xBD,0xB6,0x20,0xCE,0xBC,0xCF,
359 0x85,0xCF,0x81,0xCF,0x84,0xCE,0xB9,0xE1,0xBD,0xB2,0xCF,0x82,
360 0x20,0xCE,0xB4,0xE1,0xBD,0xB2,0xCE,0xBD,0x20,0xCE,0xB8,0xE1,
361 0xBD,0xB0,0x20,0xCE,0xB2,0xCF,0x81,0xE1,0xBF,0xB6,0x20,0xCF,
362 0x80,0xCE,0xB9,0xE1,0xBD,0xB0,0x20,0xCF,0x83,0xCF,0x84,0xE1,
363 0xBD,0xB8,0x20,0xCF,0x87,0xCF,0x81,0xCF,0x85,0xCF,0x83,0xCE,
364 0xB1,0xCF,0x86,0xE1,0xBD,0xB6,0x20,0xCE,0xBE,0xCE,0xAD,0xCF,
365 0x86,0xCF,0x89,0xCF,0x84,0xCE,0xBF
366 }, {
367 0xC3,0x81,0x72,0x76,0xC3,0xAD,0x7A,0x74,0xC5,0xB1,0x72,0xC5,
368 0x91,0x20,0x74,0xC3,0xBC,0x6B,0xC3,0xB6,0x72,0x66,0xC3,0xBA,
369 0x72,0xC3,0xB3,0x67,0xC3,0xA9,0x70
370 }, {
371 240, 144, 128, 128
372 }
373 };
374 utf8_checker utf8;
375 for(auto const& s : data)
376 {
377 static std::size_t constexpr size = 3;
378 std::size_t n = s.size();
379 consuming_buffers<
380 boost::asio::const_buffers_1> cb{
381 boost::asio::const_buffers_1(s.data(), n)};
382 streambuf sb{size};
383 while(n)
384 {
385 auto const amount = (std::min)(n, size);
386 sb.commit(buffer_copy(sb.prepare(amount), cb));
387 cb.consume(amount);
388 n -= amount;
389 }
390 BEAST_EXPECT(utf8.write(sb.data()));
391 BEAST_EXPECT(utf8.finish());
392 }
393 }
394 }
395
396 void run() override
397 {
398 testOneByteSequence();
399 testTwoByteSequence();
400 testThreeByteSequence();
401 testFourByteSequence();
402 testWithStreamBuffer();
403 }
404 };
405
406 BEAST_DEFINE_TESTSUITE(utf8_checker,websocket,beast);
407
408 } // detail
409 } // websocket
410 } // beast