• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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