| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/websockets/websocket_frame.h" | 5 #include "net/websockets/websocket_frame.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 }; | 24 }; |
| 25 static const TestCase kTests[] = { | 25 static const TestCase kTests[] = { |
| 26 { "\x81\x00", 2, GG_UINT64_C(0) }, | 26 { "\x81\x00", 2, GG_UINT64_C(0) }, |
| 27 { "\x81\x7D", 2, GG_UINT64_C(125) }, | 27 { "\x81\x7D", 2, GG_UINT64_C(125) }, |
| 28 { "\x81\x7E\x00\x7E", 4, GG_UINT64_C(126) }, | 28 { "\x81\x7E\x00\x7E", 4, GG_UINT64_C(126) }, |
| 29 { "\x81\x7E\xFF\xFF", 4, GG_UINT64_C(0xFFFF) }, | 29 { "\x81\x7E\xFF\xFF", 4, GG_UINT64_C(0xFFFF) }, |
| 30 { "\x81\x7F\x00\x00\x00\x00\x00\x01\x00\x00", 10, GG_UINT64_C(0x10000) }, | 30 { "\x81\x7F\x00\x00\x00\x00\x00\x01\x00\x00", 10, GG_UINT64_C(0x10000) }, |
| 31 { "\x81\x7F\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 10, | 31 { "\x81\x7F\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 10, |
| 32 GG_UINT64_C(0x7FFFFFFFFFFFFFFF) } | 32 GG_UINT64_C(0x7FFFFFFFFFFFFFFF) } |
| 33 }; | 33 }; |
| 34 static const int kNumTests = ARRAYSIZE_UNSAFE(kTests); | 34 static const int kNumTests = arraysize(kTests); |
| 35 | 35 |
| 36 for (int i = 0; i < kNumTests; ++i) { | 36 for (int i = 0; i < kNumTests; ++i) { |
| 37 WebSocketFrameHeader header(WebSocketFrameHeader::kOpCodeText); | 37 WebSocketFrameHeader header(WebSocketFrameHeader::kOpCodeText); |
| 38 header.final = true; | 38 header.final = true; |
| 39 header.payload_length = kTests[i].frame_length; | 39 header.payload_length = kTests[i].frame_length; |
| 40 | 40 |
| 41 std::vector<char> expected_output( | 41 std::vector<char> expected_output( |
| 42 kTests[i].frame_header, | 42 kTests[i].frame_header, |
| 43 kTests[i].frame_header + kTests[i].frame_header_length); | 43 kTests[i].frame_header + kTests[i].frame_header_length); |
| 44 std::vector<char> output(expected_output.size()); | 44 std::vector<char> output(expected_output.size()); |
| 45 EXPECT_EQ(static_cast<int>(expected_output.size()), | 45 EXPECT_EQ(static_cast<int>(expected_output.size()), |
| 46 WriteWebSocketFrameHeader( | 46 WriteWebSocketFrameHeader( |
| 47 header, NULL, &output.front(), output.size())); | 47 header, NULL, &output.front(), output.size())); |
| 48 EXPECT_EQ(expected_output, output); | 48 EXPECT_EQ(expected_output, output); |
| 49 } | 49 } |
| 50 } | 50 } |
| 51 | 51 |
| 52 TEST(WebSocketFrameHeaderTest, FrameLengthsWithMasking) { | 52 TEST(WebSocketFrameHeaderTest, FrameLengthsWithMasking) { |
| 53 static const char kMaskingKey[] = "\xDE\xAD\xBE\xEF"; | 53 static const char kMaskingKey[] = "\xDE\xAD\xBE\xEF"; |
| 54 COMPILE_ASSERT(ARRAYSIZE_UNSAFE(kMaskingKey) - 1 == | 54 COMPILE_ASSERT(arraysize(kMaskingKey) - 1 == |
| 55 WebSocketFrameHeader::kMaskingKeyLength, | 55 WebSocketFrameHeader::kMaskingKeyLength, |
| 56 incorrect_masking_key_size); | 56 incorrect_masking_key_size); |
| 57 | 57 |
| 58 struct TestCase { | 58 struct TestCase { |
| 59 const char* frame_header; | 59 const char* frame_header; |
| 60 size_t frame_header_length; | 60 size_t frame_header_length; |
| 61 uint64 frame_length; | 61 uint64 frame_length; |
| 62 }; | 62 }; |
| 63 static const TestCase kTests[] = { | 63 static const TestCase kTests[] = { |
| 64 { "\x81\x80\xDE\xAD\xBE\xEF", 6, GG_UINT64_C(0) }, | 64 { "\x81\x80\xDE\xAD\xBE\xEF", 6, GG_UINT64_C(0) }, |
| 65 { "\x81\xFD\xDE\xAD\xBE\xEF", 6, GG_UINT64_C(125) }, | 65 { "\x81\xFD\xDE\xAD\xBE\xEF", 6, GG_UINT64_C(125) }, |
| 66 { "\x81\xFE\x00\x7E\xDE\xAD\xBE\xEF", 8, GG_UINT64_C(126) }, | 66 { "\x81\xFE\x00\x7E\xDE\xAD\xBE\xEF", 8, GG_UINT64_C(126) }, |
| 67 { "\x81\xFE\xFF\xFF\xDE\xAD\xBE\xEF", 8, GG_UINT64_C(0xFFFF) }, | 67 { "\x81\xFE\xFF\xFF\xDE\xAD\xBE\xEF", 8, GG_UINT64_C(0xFFFF) }, |
| 68 { "\x81\xFF\x00\x00\x00\x00\x00\x01\x00\x00\xDE\xAD\xBE\xEF", 14, | 68 { "\x81\xFF\x00\x00\x00\x00\x00\x01\x00\x00\xDE\xAD\xBE\xEF", 14, |
| 69 GG_UINT64_C(0x10000) }, | 69 GG_UINT64_C(0x10000) }, |
| 70 { "\x81\xFF\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xDE\xAD\xBE\xEF", 14, | 70 { "\x81\xFF\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xDE\xAD\xBE\xEF", 14, |
| 71 GG_UINT64_C(0x7FFFFFFFFFFFFFFF) } | 71 GG_UINT64_C(0x7FFFFFFFFFFFFFFF) } |
| 72 }; | 72 }; |
| 73 static const int kNumTests = ARRAYSIZE_UNSAFE(kTests); | 73 static const int kNumTests = arraysize(kTests); |
| 74 | 74 |
| 75 WebSocketMaskingKey masking_key; | 75 WebSocketMaskingKey masking_key; |
| 76 std::copy(kMaskingKey, | 76 std::copy(kMaskingKey, |
| 77 kMaskingKey + WebSocketFrameHeader::kMaskingKeyLength, | 77 kMaskingKey + WebSocketFrameHeader::kMaskingKeyLength, |
| 78 masking_key.key); | 78 masking_key.key); |
| 79 | 79 |
| 80 for (int i = 0; i < kNumTests; ++i) { | 80 for (int i = 0; i < kNumTests; ++i) { |
| 81 WebSocketFrameHeader header(WebSocketFrameHeader::kOpCodeText); | 81 WebSocketFrameHeader header(WebSocketFrameHeader::kOpCodeText); |
| 82 header.final = true; | 82 header.final = true; |
| 83 header.masked = true; | 83 header.masked = true; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 112 { "\x84\x00", 2, 0x4 }, | 112 { "\x84\x00", 2, 0x4 }, |
| 113 { "\x85\x00", 2, 0x5 }, | 113 { "\x85\x00", 2, 0x5 }, |
| 114 { "\x86\x00", 2, 0x6 }, | 114 { "\x86\x00", 2, 0x6 }, |
| 115 { "\x87\x00", 2, 0x7 }, | 115 { "\x87\x00", 2, 0x7 }, |
| 116 { "\x8B\x00", 2, 0xB }, | 116 { "\x8B\x00", 2, 0xB }, |
| 117 { "\x8C\x00", 2, 0xC }, | 117 { "\x8C\x00", 2, 0xC }, |
| 118 { "\x8D\x00", 2, 0xD }, | 118 { "\x8D\x00", 2, 0xD }, |
| 119 { "\x8E\x00", 2, 0xE }, | 119 { "\x8E\x00", 2, 0xE }, |
| 120 { "\x8F\x00", 2, 0xF } | 120 { "\x8F\x00", 2, 0xF } |
| 121 }; | 121 }; |
| 122 static const int kNumTests = ARRAYSIZE_UNSAFE(kTests); | 122 static const int kNumTests = arraysize(kTests); |
| 123 | 123 |
| 124 for (int i = 0; i < kNumTests; ++i) { | 124 for (int i = 0; i < kNumTests; ++i) { |
| 125 WebSocketFrameHeader header(kTests[i].opcode); | 125 WebSocketFrameHeader header(kTests[i].opcode); |
| 126 header.final = true; | 126 header.final = true; |
| 127 header.payload_length = 0; | 127 header.payload_length = 0; |
| 128 | 128 |
| 129 std::vector<char> expected_output( | 129 std::vector<char> expected_output( |
| 130 kTests[i].frame_header, | 130 kTests[i].frame_header, |
| 131 kTests[i].frame_header + kTests[i].frame_header_length); | 131 kTests[i].frame_header + kTests[i].frame_header_length); |
| 132 std::vector<char> output(expected_output.size()); | 132 std::vector<char> output(expected_output.size()); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 148 }; | 148 }; |
| 149 static const TestCase kTests[] = { | 149 static const TestCase kTests[] = { |
| 150 { "\x81\x00", 2, true, false, false, false }, | 150 { "\x81\x00", 2, true, false, false, false }, |
| 151 { "\x01\x00", 2, false, false, false, false }, | 151 { "\x01\x00", 2, false, false, false, false }, |
| 152 { "\xC1\x00", 2, true, true, false, false }, | 152 { "\xC1\x00", 2, true, true, false, false }, |
| 153 { "\xA1\x00", 2, true, false, true, false }, | 153 { "\xA1\x00", 2, true, false, true, false }, |
| 154 { "\x91\x00", 2, true, false, false, true }, | 154 { "\x91\x00", 2, true, false, false, true }, |
| 155 { "\x71\x00", 2, false, true, true, true }, | 155 { "\x71\x00", 2, false, true, true, true }, |
| 156 { "\xF1\x00", 2, true, true, true, true } | 156 { "\xF1\x00", 2, true, true, true, true } |
| 157 }; | 157 }; |
| 158 static const int kNumTests = ARRAYSIZE_UNSAFE(kTests); | 158 static const int kNumTests = arraysize(kTests); |
| 159 | 159 |
| 160 for (int i = 0; i < kNumTests; ++i) { | 160 for (int i = 0; i < kNumTests; ++i) { |
| 161 WebSocketFrameHeader header(WebSocketFrameHeader::kOpCodeText); | 161 WebSocketFrameHeader header(WebSocketFrameHeader::kOpCodeText); |
| 162 header.final = kTests[i].final; | 162 header.final = kTests[i].final; |
| 163 header.reserved1 = kTests[i].reserved1; | 163 header.reserved1 = kTests[i].reserved1; |
| 164 header.reserved2 = kTests[i].reserved2; | 164 header.reserved2 = kTests[i].reserved2; |
| 165 header.reserved3 = kTests[i].reserved3; | 165 header.reserved3 = kTests[i].reserved3; |
| 166 header.payload_length = 0; | 166 header.payload_length = 0; |
| 167 | 167 |
| 168 std::vector<char> expected_output( | 168 std::vector<char> expected_output( |
| (...skipping 20 matching lines...) Expand all Loading... |
| 189 { GG_UINT64_C(0xFFFF), false, 4u }, | 189 { GG_UINT64_C(0xFFFF), false, 4u }, |
| 190 { GG_UINT64_C(0x10000), false, 10u }, | 190 { GG_UINT64_C(0x10000), false, 10u }, |
| 191 { GG_UINT64_C(0x7FFFFFFFFFFFFFFF), false, 10u }, | 191 { GG_UINT64_C(0x7FFFFFFFFFFFFFFF), false, 10u }, |
| 192 { GG_UINT64_C(0), true, 6u }, | 192 { GG_UINT64_C(0), true, 6u }, |
| 193 { GG_UINT64_C(125), true, 6u }, | 193 { GG_UINT64_C(125), true, 6u }, |
| 194 { GG_UINT64_C(126), true, 8u }, | 194 { GG_UINT64_C(126), true, 8u }, |
| 195 { GG_UINT64_C(0xFFFF), true, 8u }, | 195 { GG_UINT64_C(0xFFFF), true, 8u }, |
| 196 { GG_UINT64_C(0x10000), true, 14u }, | 196 { GG_UINT64_C(0x10000), true, 14u }, |
| 197 { GG_UINT64_C(0x7FFFFFFFFFFFFFFF), true, 14u } | 197 { GG_UINT64_C(0x7FFFFFFFFFFFFFFF), true, 14u } |
| 198 }; | 198 }; |
| 199 static const int kNumTests = ARRAYSIZE_UNSAFE(kTests); | 199 static const int kNumTests = arraysize(kTests); |
| 200 | 200 |
| 201 for (int i = 0; i < kNumTests; ++i) { | 201 for (int i = 0; i < kNumTests; ++i) { |
| 202 WebSocketFrameHeader header(WebSocketFrameHeader::kOpCodeText); | 202 WebSocketFrameHeader header(WebSocketFrameHeader::kOpCodeText); |
| 203 header.final = true; | 203 header.final = true; |
| 204 header.opcode = WebSocketFrameHeader::kOpCodeText; | 204 header.opcode = WebSocketFrameHeader::kOpCodeText; |
| 205 header.masked = kTests[i].masked; | 205 header.masked = kTests[i].masked; |
| 206 header.payload_length = kTests[i].payload_length; | 206 header.payload_length = kTests[i].payload_length; |
| 207 | 207 |
| 208 char dummy_buffer[14]; | 208 char dummy_buffer[14]; |
| 209 // Set an insufficient size to |buffer_size|. | 209 // Set an insufficient size to |buffer_size|. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 228 { "\xDE\xAD\xBE\xEF", 2, "FooBar", "\xF8\x80\xB1\xEF\xDF\x9D", 6 }, | 228 { "\xDE\xAD\xBE\xEF", 2, "FooBar", "\xF8\x80\xB1\xEF\xDF\x9D", 6 }, |
| 229 { "\xDE\xAD\xBE\xEF", 3, "FooBar", "\xA9\xB1\xC2\xFC\x8E\xAC", 6 }, | 229 { "\xDE\xAD\xBE\xEF", 3, "FooBar", "\xA9\xB1\xC2\xFC\x8E\xAC", 6 }, |
| 230 { "\xDE\xAD\xBE\xEF", 4, "FooBar", "\x98\xC2\xD1\xAD\xBF\xDF", 6 }, | 230 { "\xDE\xAD\xBE\xEF", 4, "FooBar", "\x98\xC2\xD1\xAD\xBF\xDF", 6 }, |
| 231 { "\xDE\xAD\xBE\xEF", 42, "FooBar", "\xF8\x80\xB1\xEF\xDF\x9D", 6 }, | 231 { "\xDE\xAD\xBE\xEF", 42, "FooBar", "\xF8\x80\xB1\xEF\xDF\x9D", 6 }, |
| 232 { "\xDE\xAD\xBE\xEF", 0, "", "", 0 }, | 232 { "\xDE\xAD\xBE\xEF", 0, "", "", 0 }, |
| 233 { "\xDE\xAD\xBE\xEF", 0, "\xDE\xAD\xBE\xEF", "\x00\x00\x00\x00", 4 }, | 233 { "\xDE\xAD\xBE\xEF", 0, "\xDE\xAD\xBE\xEF", "\x00\x00\x00\x00", 4 }, |
| 234 { "\xDE\xAD\xBE\xEF", 0, "\x00\x00\x00\x00", "\xDE\xAD\xBE\xEF", 4 }, | 234 { "\xDE\xAD\xBE\xEF", 0, "\x00\x00\x00\x00", "\xDE\xAD\xBE\xEF", 4 }, |
| 235 { "\x00\x00\x00\x00", 0, "FooBar", "FooBar", 6 }, | 235 { "\x00\x00\x00\x00", 0, "FooBar", "FooBar", 6 }, |
| 236 { "\xFF\xFF\xFF\xFF", 0, "FooBar", "\xB9\x90\x90\xBD\x9E\x8D", 6 }, | 236 { "\xFF\xFF\xFF\xFF", 0, "FooBar", "\xB9\x90\x90\xBD\x9E\x8D", 6 }, |
| 237 }; | 237 }; |
| 238 static const int kNumTests = ARRAYSIZE_UNSAFE(kTests); | 238 static const int kNumTests = arraysize(kTests); |
| 239 | 239 |
| 240 for (int i = 0; i < kNumTests; ++i) { | 240 for (int i = 0; i < kNumTests; ++i) { |
| 241 WebSocketMaskingKey masking_key; | 241 WebSocketMaskingKey masking_key; |
| 242 std::copy(kTests[i].masking_key, | 242 std::copy(kTests[i].masking_key, |
| 243 kTests[i].masking_key + WebSocketFrameHeader::kMaskingKeyLength, | 243 kTests[i].masking_key + WebSocketFrameHeader::kMaskingKeyLength, |
| 244 masking_key.key); | 244 masking_key.key); |
| 245 std::vector<char> frame_data(kTests[i].input, | 245 std::vector<char> frame_data(kTests[i].input, |
| 246 kTests[i].input + kTests[i].data_length); | 246 kTests[i].input + kTests[i].data_length); |
| 247 std::vector<char> expected_output(kTests[i].output, | 247 std::vector<char> expected_output(kTests[i].output, |
| 248 kTests[i].output + kTests[i].data_length); | 248 kTests[i].output + kTests[i].data_length); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 EXPECT_FALSE(Frame::IsKnownControlOpCode(0xF)); | 385 EXPECT_FALSE(Frame::IsKnownControlOpCode(0xF)); |
| 386 | 386 |
| 387 // Check that out-of-range opcodes return false | 387 // Check that out-of-range opcodes return false |
| 388 EXPECT_FALSE(Frame::IsKnownControlOpCode(-1)); | 388 EXPECT_FALSE(Frame::IsKnownControlOpCode(-1)); |
| 389 EXPECT_FALSE(Frame::IsKnownControlOpCode(0xFF)); | 389 EXPECT_FALSE(Frame::IsKnownControlOpCode(0xFF)); |
| 390 } | 390 } |
| 391 | 391 |
| 392 } // namespace | 392 } // namespace |
| 393 | 393 |
| 394 } // namespace net | 394 } // namespace net |
| OLD | NEW |