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