• 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_extension_parser.h"
6 
7 #include <string>
8 
9 #include "net/websockets/websocket_extension.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 
12 namespace net {
13 
14 namespace {
15 
TEST(WebSocketExtensionParserTest,ParseEmpty)16 TEST(WebSocketExtensionParserTest, ParseEmpty) {
17   WebSocketExtensionParser parser;
18   EXPECT_FALSE(parser.Parse("", 0));
19 
20   EXPECT_EQ(0U, parser.extensions().size());
21 }
22 
TEST(WebSocketExtensionParserTest,ParseSimple)23 TEST(WebSocketExtensionParserTest, ParseSimple) {
24   WebSocketExtensionParser parser;
25   WebSocketExtension expected("foo");
26 
27   EXPECT_TRUE(parser.Parse("foo"));
28 
29   ASSERT_EQ(1U, parser.extensions().size());
30   EXPECT_TRUE(expected.Equals(parser.extensions()[0]));
31 }
32 
TEST(WebSocketExtensionParserTest,ParseMoreThanOnce)33 TEST(WebSocketExtensionParserTest, ParseMoreThanOnce) {
34   WebSocketExtensionParser parser;
35   WebSocketExtension expected("foo");
36 
37   EXPECT_TRUE(parser.Parse("foo"));
38   ASSERT_EQ(1U, parser.extensions().size());
39   EXPECT_TRUE(expected.Equals(parser.extensions()[0]));
40 
41   EXPECT_FALSE(parser.Parse(""));
42   EXPECT_EQ(0U, parser.extensions().size());
43 
44   EXPECT_TRUE(parser.Parse("foo"));
45   ASSERT_EQ(1U, parser.extensions().size());
46   EXPECT_TRUE(expected.Equals(parser.extensions()[0]));
47 }
48 
TEST(WebSocketExtensionParserTest,ParseOneExtensionWithOneParamWithoutValue)49 TEST(WebSocketExtensionParserTest, ParseOneExtensionWithOneParamWithoutValue) {
50   WebSocketExtensionParser parser;
51   WebSocketExtension expected("foo");
52   expected.Add(WebSocketExtension::Parameter("bar"));
53 
54   EXPECT_TRUE(parser.Parse("\tfoo ; bar"));
55 
56   ASSERT_EQ(1U, parser.extensions().size());
57   EXPECT_TRUE(expected.Equals(parser.extensions()[0]));
58 }
59 
TEST(WebSocketExtensionParserTest,ParseOneExtensionWithOneParamWithValue)60 TEST(WebSocketExtensionParserTest, ParseOneExtensionWithOneParamWithValue) {
61   WebSocketExtensionParser parser;
62   WebSocketExtension expected("foo");
63   expected.Add(WebSocketExtension::Parameter("bar", "baz"));
64 
65   EXPECT_TRUE(parser.Parse("foo ; bar= baz\t"));
66 
67   ASSERT_EQ(1U, parser.extensions().size());
68   EXPECT_TRUE(expected.Equals(parser.extensions()[0]));
69 }
70 
TEST(WebSocketExtensionParserTest,ParseOneExtensionWithParams)71 TEST(WebSocketExtensionParserTest, ParseOneExtensionWithParams) {
72   WebSocketExtensionParser parser;
73   WebSocketExtension expected("foo");
74   expected.Add(WebSocketExtension::Parameter("bar", "baz"));
75   expected.Add(WebSocketExtension::Parameter("hoge", "fuga"));
76 
77   EXPECT_TRUE(parser.Parse("foo ; bar= baz;\t \thoge\t\t=fuga"));
78 
79   ASSERT_EQ(1U, parser.extensions().size());
80   EXPECT_TRUE(expected.Equals(parser.extensions()[0]));
81 }
82 
TEST(WebSocketExtensionParserTest,ParseTwoExtensions)83 TEST(WebSocketExtensionParserTest, ParseTwoExtensions) {
84   WebSocketExtensionParser parser;
85 
86   WebSocketExtension expected0("foo");
87   expected0.Add(WebSocketExtension::Parameter("alpha", "x"));
88 
89   WebSocketExtension expected1("bar");
90   expected1.Add(WebSocketExtension::Parameter("beta", "y"));
91 
92   EXPECT_TRUE(parser.Parse(" foo ; alpha = x , bar ; beta = y "));
93 
94   ASSERT_EQ(2U, parser.extensions().size());
95 
96   EXPECT_TRUE(expected0.Equals(parser.extensions()[0]));
97   EXPECT_TRUE(expected1.Equals(parser.extensions()[1]));
98 }
99 
TEST(WebSocketExtensionParserTest,InvalidPatterns)100 TEST(WebSocketExtensionParserTest, InvalidPatterns) {
101   const char* const patterns[] = {
102       ",",                    // just a comma
103       " , ",                  // just a comma with surrounding spaces
104       "foo,",                 // second extension is incomplete (empty)
105       "foo , ",               // second extension is incomplete (space)
106       "foo,;",                // second extension is incomplete (semicolon)
107       "foo;, bar",            // first extension is incomplete
108       "fo\ao",                // control in extension name
109       "fo\x01o",              // control in extension name
110       "fo<o",                 // separator in extension name
111       "foo/",                 // separator in extension name
112       ";bar",                 // empty extension name
113       "foo bar",              // missing ';'
114       "foo;",                 // extension parameter without name and value
115       "foo; b\ar",            // control in parameter name
116       "foo; b\x7fr",          // control in parameter name
117       "foo; b[r",             // separator in parameter name
118       "foo; ba:",             // separator in parameter name
119       "foo; =baz",            // empty parameter name
120       "foo; bar=",            // empty parameter value
121       "foo; =",               // empty parameter name and value
122       "foo; bar=b\x02z",      // control in parameter value
123       "foo; bar=b@z",         // separator in parameter value
124       "foo; bar=b\\z",        // separator in parameter value
125       "foo; bar=b?z",         // separator in parameter value
126       "\"foo\"",              // quoted extension name
127       "foo; \"bar\"",         // quoted parameter name
128       "foo; bar=\"\a2\"",     // control in quoted parameter value
129       "foo; bar=\"b@z\"",     // separator in quoted parameter value
130       "foo; bar=\"b\\\\z\"",  // separator in quoted parameter value
131       "foo; bar=\"\"",        // quoted empty parameter value
132       "foo; bar=\"baz",       // unterminated quoted string
133       "foo; bar=\"baz \"",    // space in quoted string
134       "foo; bar baz",         // missing '='
135       "foo; bar - baz",  // '-' instead of '=' (note: "foo; bar-baz" is valid).
136       "foo; bar=\r\nbaz",   // CRNL not followed by a space
137       "foo; bar=\r\n baz",  // CRNL followed by a space
138       "f\xFFpp",            // 8-bit character in extension name
139       "foo; b\xFFr=baz"     // 8-bit character in parameter name
140       "foo; bar=b\xFF"      // 8-bit character in parameter value
141       "foo; bar=\"b\xFF\""  // 8-bit character in quoted parameter value
142       "foo; bar=\"baz\\"    // ends with backslash
143   };
144 
145   for (const auto* pattern : patterns) {
146     WebSocketExtensionParser parser;
147     EXPECT_FALSE(parser.Parse(pattern));
148     EXPECT_EQ(0U, parser.extensions().size());
149   }
150 }
151 
TEST(WebSocketExtensionParserTest,QuotedParameterValue)152 TEST(WebSocketExtensionParserTest, QuotedParameterValue) {
153   WebSocketExtensionParser parser;
154   WebSocketExtension expected("foo");
155   expected.Add(WebSocketExtension::Parameter("bar", "baz"));
156 
157   EXPECT_TRUE(parser.Parse("foo; bar = \"ba\\z\" "));
158 
159   ASSERT_EQ(1U, parser.extensions().size());
160   EXPECT_TRUE(expected.Equals(parser.extensions()[0]));
161 }
162 
163 // This is a regression test for crbug.com/647156
TEST(WebSocketExtensionParserTest,InvalidToken)164 TEST(WebSocketExtensionParserTest, InvalidToken) {
165   static const char kInvalidInput[] = "\304;\304!*777\377=\377\254\377";
166   WebSocketExtensionParser parser;
167   EXPECT_FALSE(parser.Parse(kInvalidInput));
168 }
169 
170 }  // namespace
171 
172 }  // namespace net
173