1 // Copyright 2013 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/websockets/websocket_frame_parser.h"
6
7 #include <stdint.h>
8
9 #include <algorithm>
10 #include <iterator>
11 #include <string>
12 #include <vector>
13
14 #include "net/websockets/websocket_frame.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace net {
18
19 namespace {
20
21 const char kHello[] = "Hello, world!";
22 const uint64_t kHelloLength = std::size(kHello) - 1;
23 const char kHelloFrame[] = "\x81\x0DHello, world!";
24 const uint64_t kHelloFrameLength = std::size(kHelloFrame) - 1;
25 const char kMaskedHelloFrame[] =
26 "\x81\x8D\xDE\xAD\xBE\xEF"
27 "\x96\xC8\xD2\x83\xB1\x81\x9E\x98\xB1\xDF\xD2\x8B\xFF";
28 const uint64_t kMaskedHelloFrameLength = std::size(kMaskedHelloFrame) - 1;
29
30 struct FrameHeaderTestCase {
31 const char* frame_header;
32 size_t frame_header_length;
33 uint64_t frame_length;
34 WebSocketError error_code;
35 };
36
37 const FrameHeaderTestCase kFrameHeaderTests[] = {
38 { "\x81\x00", 2, UINT64_C(0), kWebSocketNormalClosure },
39 { "\x81\x7D", 2, UINT64_C(125), kWebSocketNormalClosure },
40 { "\x81\x7E\x00\x7E", 4, UINT64_C(126), kWebSocketNormalClosure },
41 { "\x81\x7E\xFF\xFF", 4, UINT64_C(0xFFFF), kWebSocketNormalClosure },
42 { "\x81\x7F\x00\x00\x00\x00\x00\x01\x00\x00", 10, UINT64_C(0x10000),
43 kWebSocketNormalClosure },
44 { "\x81\x7F\x00\x00\x00\x00\x7F\xFF\xFF\xFF", 10, UINT64_C(0x7FFFFFFF),
45 kWebSocketNormalClosure },
46 { "\x81\x7F\x00\x00\x00\x00\x80\x00\x00\x00", 10, UINT64_C(0x80000000),
47 kWebSocketErrorMessageTooBig },
48 { "\x81\x7F\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 10,
49 UINT64_C(0x7FFFFFFFFFFFFFFF), kWebSocketErrorMessageTooBig }
50 };
51 const int kNumFrameHeaderTests = std::size(kFrameHeaderTests);
52
TEST(WebSocketFrameParserTest,DecodeNormalFrame)53 TEST(WebSocketFrameParserTest, DecodeNormalFrame) {
54 WebSocketFrameParser parser;
55
56 std::vector<std::unique_ptr<WebSocketFrameChunk>> frames;
57 EXPECT_TRUE(parser.Decode(kHelloFrame, kHelloFrameLength, &frames));
58 EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
59 ASSERT_EQ(1u, frames.size());
60 WebSocketFrameChunk* frame = frames[0].get();
61 ASSERT_TRUE(frame != nullptr);
62 const WebSocketFrameHeader* header = frame->header.get();
63 EXPECT_TRUE(header != nullptr);
64 if (header) {
65 EXPECT_TRUE(header->final);
66 EXPECT_FALSE(header->reserved1);
67 EXPECT_FALSE(header->reserved2);
68 EXPECT_FALSE(header->reserved3);
69 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, header->opcode);
70 EXPECT_FALSE(header->masked);
71 EXPECT_EQ(kHelloLength, header->payload_length);
72 }
73 EXPECT_TRUE(frame->final_chunk);
74
75 ASSERT_EQ(static_cast<size_t>(kHelloLength), frame->payload.size());
76 EXPECT_TRUE(std::equal(kHello, kHello + kHelloLength, frame->payload.data()));
77 }
78
TEST(WebSocketFrameParserTest,DecodeMaskedFrame)79 TEST(WebSocketFrameParserTest, DecodeMaskedFrame) {
80 WebSocketFrameParser parser;
81
82 std::vector<std::unique_ptr<WebSocketFrameChunk>> frames;
83 EXPECT_TRUE(
84 parser.Decode(kMaskedHelloFrame, kMaskedHelloFrameLength, &frames));
85 EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
86 ASSERT_EQ(1u, frames.size());
87 WebSocketFrameChunk* frame = frames[0].get();
88 ASSERT_TRUE(frame != nullptr);
89 const WebSocketFrameHeader* header = frame->header.get();
90 EXPECT_TRUE(header != nullptr);
91 if (header) {
92 EXPECT_TRUE(header->final);
93 EXPECT_FALSE(header->reserved1);
94 EXPECT_FALSE(header->reserved2);
95 EXPECT_FALSE(header->reserved3);
96 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, header->opcode);
97 EXPECT_TRUE(header->masked);
98 EXPECT_EQ(kHelloLength, header->payload_length);
99 }
100 EXPECT_TRUE(frame->final_chunk);
101
102 ASSERT_EQ(static_cast<size_t>(kHelloLength), frame->payload.size());
103
104 std::string payload(frame->payload.data(), frame->payload.size());
105 MaskWebSocketFramePayload(header->masking_key, 0, &payload[0],
106 payload.size());
107 EXPECT_EQ(payload, kHello);
108 }
109
TEST(WebSocketFrameParserTest,DecodeManyFrames)110 TEST(WebSocketFrameParserTest, DecodeManyFrames) {
111 struct Input {
112 const char* frame;
113 size_t frame_length;
114 const char* expected_payload;
115 size_t expected_payload_length;
116 };
117 static const Input kInputs[] = {
118 // Each |frame| data is split into two string literals because C++ lexers
119 // consume unlimited number of hex characters in a hex character escape
120 // (e.g. "\x05F" is not treated as { '\x5', 'F', '\0' } but as
121 // { '\x5F', '\0' }).
122 { "\x81\x05" "First", 7, "First", 5 },
123 { "\x81\x06" "Second", 8, "Second", 6 },
124 { "\x81\x05" "Third", 7, "Third", 5 },
125 { "\x81\x06" "Fourth", 8, "Fourth", 6 },
126 { "\x81\x05" "Fifth", 7, "Fifth", 5 },
127 { "\x81\x05" "Sixth", 7, "Sixth", 5 },
128 { "\x81\x07" "Seventh", 9, "Seventh", 7 },
129 { "\x81\x06" "Eighth", 8, "Eighth", 6 },
130 { "\x81\x05" "Ninth", 7, "Ninth", 5 },
131 { "\x81\x05" "Tenth", 7, "Tenth", 5 }
132 };
133 static const int kNumInputs = std::size(kInputs);
134
135 std::vector<char> input;
136 // Concatenate all frames.
137 for (const auto& data : kInputs) {
138 input.insert(input.end(), data.frame, data.frame + data.frame_length);
139 }
140
141 WebSocketFrameParser parser;
142
143 std::vector<std::unique_ptr<WebSocketFrameChunk>> frames;
144 EXPECT_TRUE(parser.Decode(input.data(), input.size(), &frames));
145 EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
146 ASSERT_EQ(static_cast<size_t>(kNumInputs), frames.size());
147
148 for (int i = 0; i < kNumInputs; ++i) {
149 WebSocketFrameChunk* frame = frames[i].get();
150 EXPECT_TRUE(frame != nullptr);
151 if (!frame)
152 continue;
153 EXPECT_TRUE(frame->final_chunk);
154 ASSERT_EQ(kInputs[i].expected_payload_length,
155 static_cast<uint64_t>(frame->payload.size()));
156 EXPECT_TRUE(std::equal(
157 kInputs[i].expected_payload,
158 kInputs[i].expected_payload + kInputs[i].expected_payload_length,
159 frame->payload.data()));
160
161 const WebSocketFrameHeader* header = frame->header.get();
162 EXPECT_TRUE(header != nullptr);
163 if (!header)
164 continue;
165 EXPECT_TRUE(header->final);
166 EXPECT_FALSE(header->reserved1);
167 EXPECT_FALSE(header->reserved2);
168 EXPECT_FALSE(header->reserved3);
169 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, header->opcode);
170 EXPECT_FALSE(header->masked);
171 EXPECT_EQ(kInputs[i].expected_payload_length, header->payload_length);
172 }
173 }
174
TEST(WebSocketFrameParserTest,DecodePartialFrame)175 TEST(WebSocketFrameParserTest, DecodePartialFrame) {
176 static const size_t kFrameHeaderSize = 2;
177
178 for (size_t cutting_pos = 0; cutting_pos < kHelloLength; ++cutting_pos) {
179 std::vector<char> input1(kHelloFrame,
180 kHelloFrame + kFrameHeaderSize + cutting_pos);
181 std::vector<char> input2(kHelloFrame + input1.size(),
182 kHelloFrame + kHelloFrameLength);
183
184 std::vector<char> expected1(kHello, kHello + cutting_pos);
185 std::vector<char> expected2(kHello + cutting_pos, kHello + kHelloLength);
186
187 WebSocketFrameParser parser;
188
189 std::vector<std::unique_ptr<WebSocketFrameChunk>> frames1;
190 EXPECT_TRUE(parser.Decode(&input1.front(), input1.size(), &frames1));
191 EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
192 EXPECT_EQ(1u, frames1.size());
193 if (frames1.size() != 1u)
194 continue;
195 WebSocketFrameChunk* frame1 = frames1[0].get();
196 EXPECT_TRUE(frame1 != nullptr);
197 if (!frame1)
198 continue;
199 EXPECT_FALSE(frame1->final_chunk);
200 if (expected1.size() == 0) {
201 EXPECT_EQ(nullptr, frame1->payload.data());
202 } else {
203 ASSERT_EQ(cutting_pos, static_cast<size_t>(frame1->payload.size()));
204 EXPECT_TRUE(std::equal(expected1.begin(), expected1.end(),
205 frame1->payload.data()));
206 }
207 const WebSocketFrameHeader* header1 = frame1->header.get();
208 EXPECT_TRUE(header1 != nullptr);
209 if (!header1)
210 continue;
211 EXPECT_TRUE(header1->final);
212 EXPECT_FALSE(header1->reserved1);
213 EXPECT_FALSE(header1->reserved2);
214 EXPECT_FALSE(header1->reserved3);
215 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, header1->opcode);
216 EXPECT_FALSE(header1->masked);
217 EXPECT_EQ(kHelloLength, header1->payload_length);
218
219 std::vector<std::unique_ptr<WebSocketFrameChunk>> frames2;
220 EXPECT_TRUE(parser.Decode(&input2.front(), input2.size(), &frames2));
221 EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
222 EXPECT_EQ(1u, frames2.size());
223 if (frames2.size() != 1u)
224 continue;
225 WebSocketFrameChunk* frame2 = frames2[0].get();
226 EXPECT_TRUE(frame2 != nullptr);
227 if (!frame2)
228 continue;
229 EXPECT_TRUE(frame2->final_chunk);
230 if (expected2.size() == 0) {
231 EXPECT_EQ(nullptr, frame1->payload.data());
232 } else {
233 ASSERT_EQ(expected2.size(),
234 static_cast<uint64_t>(frame2->payload.size()));
235 EXPECT_TRUE(std::equal(expected2.begin(), expected2.end(),
236 frame2->payload.data()));
237 }
238 const WebSocketFrameHeader* header2 = frame2->header.get();
239 EXPECT_TRUE(header2 == nullptr);
240 }
241 }
242
TEST(WebSocketFrameParserTest,DecodePartialMaskedFrame)243 TEST(WebSocketFrameParserTest, DecodePartialMaskedFrame) {
244 static const size_t kFrameHeaderSize = 6;
245
246 for (size_t cutting_pos = 0; cutting_pos < kHelloLength; ++cutting_pos) {
247 std::vector<char> input1(
248 kMaskedHelloFrame, kMaskedHelloFrame + kFrameHeaderSize + cutting_pos);
249 std::vector<char> input2(kMaskedHelloFrame + input1.size(),
250 kMaskedHelloFrame + kMaskedHelloFrameLength);
251
252 std::vector<char> expected1(kHello, kHello + cutting_pos);
253 std::vector<char> expected2(kHello + cutting_pos, kHello + kHelloLength);
254
255 WebSocketFrameParser parser;
256
257 std::vector<std::unique_ptr<WebSocketFrameChunk>> frames1;
258 EXPECT_TRUE(parser.Decode(&input1.front(), input1.size(), &frames1));
259 EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
260 EXPECT_EQ(1u, frames1.size());
261 if (frames1.size() != 1u)
262 continue;
263 WebSocketFrameChunk* frame1 = frames1[0].get();
264 EXPECT_TRUE(frame1 != nullptr);
265 if (!frame1)
266 continue;
267 EXPECT_FALSE(frame1->final_chunk);
268 const WebSocketFrameHeader* header1 = frame1->header.get();
269 EXPECT_TRUE(header1 != nullptr);
270 if (!header1)
271 continue;
272 if (expected1.size() == 0) {
273 EXPECT_EQ(nullptr, frame1->payload.data());
274 } else {
275 ASSERT_EQ(expected1.size(),
276 static_cast<uint64_t>(frame1->payload.size()));
277 std::vector<char> payload1(
278 frame1->payload.data(),
279 frame1->payload.data() + frame1->payload.size());
280 MaskWebSocketFramePayload(header1->masking_key, 0, &payload1[0],
281 payload1.size());
282 EXPECT_EQ(expected1, payload1);
283 }
284 EXPECT_TRUE(header1->final);
285 EXPECT_FALSE(header1->reserved1);
286 EXPECT_FALSE(header1->reserved2);
287 EXPECT_FALSE(header1->reserved3);
288 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, header1->opcode);
289 EXPECT_TRUE(header1->masked);
290 EXPECT_EQ(kHelloLength, header1->payload_length);
291
292 std::vector<std::unique_ptr<WebSocketFrameChunk>> frames2;
293 EXPECT_TRUE(parser.Decode(&input2.front(), input2.size(), &frames2));
294 EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
295 EXPECT_EQ(1u, frames2.size());
296 if (frames2.size() != 1u)
297 continue;
298 WebSocketFrameChunk* frame2 = frames2[0].get();
299 EXPECT_TRUE(frame2 != nullptr);
300 if (!frame2)
301 continue;
302 EXPECT_TRUE(frame2->final_chunk);
303 if (expected2.size() == 0) {
304 EXPECT_EQ(nullptr, frame2->payload.data());
305 } else {
306 ASSERT_EQ(expected2.size(),
307 static_cast<uint64_t>(frame2->payload.size()));
308 std::vector<char> payload2(
309 frame2->payload.data(),
310 frame2->payload.data() + frame2->payload.size());
311 MaskWebSocketFramePayload(header1->masking_key, cutting_pos, &payload2[0],
312 payload2.size());
313 EXPECT_EQ(expected2, payload2);
314 }
315 const WebSocketFrameHeader* header2 = frame2->header.get();
316 EXPECT_TRUE(header2 == nullptr);
317 }
318 }
319
TEST(WebSocketFrameParserTest,DecodeFramesOfVariousLengths)320 TEST(WebSocketFrameParserTest, DecodeFramesOfVariousLengths) {
321 for (const auto& test : kFrameHeaderTests) {
322 const char* frame_header = test.frame_header;
323 size_t frame_header_length = test.frame_header_length;
324 uint64_t frame_length = test.frame_length;
325
326 std::vector<char> input(frame_header, frame_header + frame_header_length);
327 // Limit the payload size not to flood the console on failure.
328 static const uint64_t kMaxPayloadSize = 200;
329 uint64_t input_payload_size = std::min(frame_length, kMaxPayloadSize);
330 input.insert(input.end(), input_payload_size, 'a');
331
332 WebSocketFrameParser parser;
333
334 std::vector<std::unique_ptr<WebSocketFrameChunk>> frames;
335 EXPECT_EQ(test.error_code == kWebSocketNormalClosure,
336 parser.Decode(input.data(), input.size(), &frames));
337 EXPECT_EQ(test.error_code, parser.websocket_error());
338 if (test.error_code != kWebSocketNormalClosure) {
339 EXPECT_EQ(0u, frames.size());
340 } else {
341 EXPECT_EQ(1u, frames.size());
342 }
343 if (frames.size() != 1u)
344 continue;
345 WebSocketFrameChunk* frame = frames[0].get();
346 EXPECT_TRUE(frame != nullptr);
347 if (!frame)
348 continue;
349 if (frame_length == input_payload_size) {
350 EXPECT_TRUE(frame->final_chunk);
351 } else {
352 EXPECT_FALSE(frame->final_chunk);
353 }
354 std::vector<char> expected_payload(input_payload_size, 'a');
355 if (expected_payload.size() == 0) {
356 EXPECT_EQ(nullptr, frame->payload.data());
357 } else {
358 ASSERT_EQ(expected_payload.size(),
359 static_cast<uint64_t>(frame->payload.size()));
360 EXPECT_TRUE(std::equal(expected_payload.begin(), expected_payload.end(),
361 frame->payload.data()));
362 }
363 const WebSocketFrameHeader* header = frame->header.get();
364 EXPECT_TRUE(header != nullptr);
365 if (!header)
366 continue;
367 EXPECT_TRUE(header->final);
368 EXPECT_FALSE(header->reserved1);
369 EXPECT_FALSE(header->reserved2);
370 EXPECT_FALSE(header->reserved3);
371 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, header->opcode);
372 EXPECT_FALSE(header->masked);
373 EXPECT_EQ(frame_length, header->payload_length);
374 }
375 }
376
TEST(WebSocketFrameParserTest,DecodePartialHeader)377 TEST(WebSocketFrameParserTest, DecodePartialHeader) {
378 for (int i = 0; i < kNumFrameHeaderTests; ++i) {
379 const char* frame_header = kFrameHeaderTests[i].frame_header;
380 size_t frame_header_length = kFrameHeaderTests[i].frame_header_length;
381 uint64_t frame_length = kFrameHeaderTests[i].frame_length;
382
383 WebSocketFrameParser parser;
384
385 std::vector<std::unique_ptr<WebSocketFrameChunk>> frames;
386 // Feed each byte to the parser to see if the parser behaves correctly
387 // when it receives partial frame header.
388 size_t last_byte_offset = frame_header_length - 1;
389 for (size_t j = 0; j < frame_header_length; ++j) {
390 bool failed =
391 kFrameHeaderTests[i].error_code != kWebSocketNormalClosure &&
392 j == last_byte_offset;
393 EXPECT_EQ(!failed, parser.Decode(frame_header + j, 1, &frames));
394 if (failed) {
395 EXPECT_EQ(kFrameHeaderTests[i].error_code, parser.websocket_error());
396 } else {
397 EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
398 }
399 if (kFrameHeaderTests[i].error_code == kWebSocketNormalClosure &&
400 j == last_byte_offset) {
401 EXPECT_EQ(1u, frames.size()) << "i=" << i << ", j=" << j;
402 } else {
403 EXPECT_EQ(0u, frames.size()) << "i=" << i << ", j=" << j;
404 }
405 }
406 if (frames.size() != 1u)
407 continue;
408 WebSocketFrameChunk* frame = frames[0].get();
409 EXPECT_TRUE(frame != nullptr);
410 if (!frame)
411 continue;
412 if (frame_length == 0u) {
413 EXPECT_TRUE(frame->final_chunk);
414 } else {
415 EXPECT_FALSE(frame->final_chunk);
416 }
417 EXPECT_EQ(nullptr, frame->payload.data());
418 const WebSocketFrameHeader* header = frame->header.get();
419 EXPECT_TRUE(header != nullptr);
420 if (!header)
421 continue;
422 EXPECT_TRUE(header->final);
423 EXPECT_FALSE(header->reserved1);
424 EXPECT_FALSE(header->reserved2);
425 EXPECT_FALSE(header->reserved3);
426 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, header->opcode);
427 EXPECT_FALSE(header->masked);
428 EXPECT_EQ(frame_length, header->payload_length);
429 }
430 }
431
TEST(WebSocketFrameParserTest,InvalidLengthEncoding)432 TEST(WebSocketFrameParserTest, InvalidLengthEncoding) {
433 struct TestCase {
434 const char* frame_header;
435 size_t frame_header_length;
436 };
437 static const TestCase kTests[] = {
438 // For frames with two-byte extended length field, the payload length
439 // should be 126 (0x7E) bytes or more.
440 {"\x81\x7E\x00\x00", 4},
441 {"\x81\x7E\x00\x7D", 4},
442 // For frames with eight-byte extended length field, the payload length
443 // should be 0x10000 bytes or more.
444 {"\x81\x7F\x00\x00\x00\x00\x00\x00\x00\x00", 10},
445 {"\x81\x7E\x00\x00\x00\x00\x00\x00\xFF\xFF", 10},
446 };
447
448 for (const auto& test : kTests) {
449 const char* frame_header = test.frame_header;
450 size_t frame_header_length = test.frame_header_length;
451
452 WebSocketFrameParser parser;
453
454 std::vector<std::unique_ptr<WebSocketFrameChunk>> frames;
455 EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
456 EXPECT_FALSE(parser.Decode(frame_header, frame_header_length, &frames));
457 EXPECT_EQ(kWebSocketErrorProtocolError, parser.websocket_error());
458 EXPECT_EQ(0u, frames.size());
459
460 // Once the parser has failed, it no longer accepts any input (even if
461 // the input is empty).
462 EXPECT_FALSE(parser.Decode("", 0, &frames));
463 EXPECT_EQ(kWebSocketErrorProtocolError, parser.websocket_error());
464 EXPECT_EQ(0u, frames.size());
465 }
466 }
467
TEST(WebSocketFrameParserTest,FrameTypes)468 TEST(WebSocketFrameParserTest, FrameTypes) {
469 struct TestCase {
470 const char* frame_header;
471 size_t frame_header_length;
472 WebSocketFrameHeader::OpCode opcode;
473 };
474 static const TestCase kTests[] = {
475 {"\x80\x00", 2, WebSocketFrameHeader::kOpCodeContinuation},
476 {"\x81\x00", 2, WebSocketFrameHeader::kOpCodeText},
477 {"\x82\x00", 2, WebSocketFrameHeader::kOpCodeBinary},
478 {"\x88\x00", 2, WebSocketFrameHeader::kOpCodeClose},
479 {"\x89\x00", 2, WebSocketFrameHeader::kOpCodePing},
480 {"\x8A\x00", 2, WebSocketFrameHeader::kOpCodePong},
481 // These are undefined opcodes, but the parser needs to be able to parse
482 // them anyway.
483 {"\x83\x00", 2, 0x3},
484 {"\x84\x00", 2, 0x4},
485 {"\x85\x00", 2, 0x5},
486 {"\x86\x00", 2, 0x6},
487 {"\x87\x00", 2, 0x7},
488 {"\x8B\x00", 2, 0xB},
489 {"\x8C\x00", 2, 0xC},
490 {"\x8D\x00", 2, 0xD},
491 {"\x8E\x00", 2, 0xE},
492 {"\x8F\x00", 2, 0xF}};
493
494 for (const auto& test : kTests) {
495 const char* frame_header = test.frame_header;
496 size_t frame_header_length = test.frame_header_length;
497 WebSocketFrameHeader::OpCode opcode = test.opcode;
498
499 WebSocketFrameParser parser;
500
501 std::vector<std::unique_ptr<WebSocketFrameChunk>> frames;
502 EXPECT_TRUE(parser.Decode(frame_header, frame_header_length, &frames));
503 EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
504 EXPECT_EQ(1u, frames.size());
505 if (frames.size() != 1u)
506 continue;
507 WebSocketFrameChunk* frame = frames[0].get();
508 EXPECT_TRUE(frame != nullptr);
509 if (!frame)
510 continue;
511 EXPECT_TRUE(frame->final_chunk);
512 EXPECT_EQ(nullptr, frame->payload.data());
513 const WebSocketFrameHeader* header = frame->header.get();
514 EXPECT_TRUE(header != nullptr);
515 if (!header)
516 continue;
517 EXPECT_TRUE(header->final);
518 EXPECT_FALSE(header->reserved1);
519 EXPECT_FALSE(header->reserved2);
520 EXPECT_FALSE(header->reserved3);
521 EXPECT_EQ(opcode, header->opcode);
522 EXPECT_FALSE(header->masked);
523 EXPECT_EQ(0u, header->payload_length);
524 }
525 }
526
TEST(WebSocketFrameParserTest,FinalBitAndReservedBits)527 TEST(WebSocketFrameParserTest, FinalBitAndReservedBits) {
528 struct TestCase {
529 const char* frame_header;
530 size_t frame_header_length;
531 bool final;
532 bool reserved1;
533 bool reserved2;
534 bool reserved3;
535 };
536 static const TestCase kTests[] = {
537 { "\x81\x00", 2, true, false, false, false },
538 { "\x01\x00", 2, false, false, false, false },
539 { "\xC1\x00", 2, true, true, false, false },
540 { "\xA1\x00", 2, true, false, true, false },
541 { "\x91\x00", 2, true, false, false, true },
542 { "\x71\x00", 2, false, true, true, true },
543 { "\xF1\x00", 2, true, true, true, true }
544 };
545
546 for (const auto& test : kTests) {
547 const char* frame_header = test.frame_header;
548 size_t frame_header_length = test.frame_header_length;
549 bool final = test.final;
550 bool reserved1 = test.reserved1;
551 bool reserved2 = test.reserved2;
552 bool reserved3 = test.reserved3;
553
554 WebSocketFrameParser parser;
555
556 std::vector<std::unique_ptr<WebSocketFrameChunk>> frames;
557 EXPECT_TRUE(parser.Decode(frame_header, frame_header_length, &frames));
558 EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
559 EXPECT_EQ(1u, frames.size());
560 if (frames.size() != 1u)
561 continue;
562 WebSocketFrameChunk* frame = frames[0].get();
563 EXPECT_TRUE(frame != nullptr);
564 if (!frame)
565 continue;
566 EXPECT_TRUE(frame->final_chunk);
567 EXPECT_EQ(nullptr, frame->payload.data());
568 const WebSocketFrameHeader* header = frame->header.get();
569 EXPECT_TRUE(header != nullptr);
570 if (!header)
571 continue;
572 EXPECT_EQ(final, header->final);
573 EXPECT_EQ(reserved1, header->reserved1);
574 EXPECT_EQ(reserved2, header->reserved2);
575 EXPECT_EQ(reserved3, header->reserved3);
576 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, header->opcode);
577 EXPECT_FALSE(header->masked);
578 EXPECT_EQ(0u, header->payload_length);
579 }
580 }
581
582 } // Unnamed namespace
583
584 } // namespace net
585