Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(787)

Side by Side Diff: net/websockets/websocket_extension_parser.cc

Issue 2344873002: WebSocketExtensionParser: reject top-bit-set characters (Closed)
Patch Set: Include logging.h, remove string_util.h Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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_extension_parser.h" 5 #include "net/websockets/websocket_extension_parser.h"
6 6
7 #include "base/strings/string_util.h" 7 #include "base/logging.h"
8 #include "net/http/http_util.h"
8 9
9 namespace net { 10 namespace net {
10 11
11 WebSocketExtensionParser::WebSocketExtensionParser() {} 12 WebSocketExtensionParser::WebSocketExtensionParser() {}
12 13
13 WebSocketExtensionParser::~WebSocketExtensionParser() {} 14 WebSocketExtensionParser::~WebSocketExtensionParser() {}
14 15
15 bool WebSocketExtensionParser::Parse(const char* data, size_t size) { 16 bool WebSocketExtensionParser::Parse(const char* data, size_t size) {
16 current_ = data; 17 current_ = data;
17 end_ = data + size; 18 end_ = data + size;
18 extensions_.clear(); 19 extensions_.clear();
19 20
20 bool failed = false; 21 bool failed = false;
21 22
22 while (true) { 23 do {
23 WebSocketExtension extension; 24 WebSocketExtension extension;
24 if (!ConsumeExtension(&extension)) { 25 if (!ConsumeExtension(&extension)) {
25 failed = true; 26 failed = true;
26 break; 27 break;
27 } 28 }
28 extensions_.push_back(extension); 29 extensions_.push_back(extension);
29 30
30 ConsumeSpaces(); 31 ConsumeSpaces();
31 32 } while (ConsumeIfMatch(','));
32 if (!ConsumeIfMatch(',')) {
33 break;
34 }
35 }
36 33
37 if (!failed && current_ == end_) 34 if (!failed && current_ == end_)
38 return true; 35 return true;
39 36
40 extensions_.clear(); 37 extensions_.clear();
41 return false; 38 return false;
42 } 39 }
43 40
44 bool WebSocketExtensionParser::Consume(char c) { 41 bool WebSocketExtensionParser::Consume(char c) {
45 ConsumeSpaces(); 42 ConsumeSpaces();
46 if (current_ == end_ || c != current_[0]) { 43 if (current_ == end_ || c != *current_)
47 return false; 44 return false;
48 }
49 ++current_; 45 ++current_;
50 return true; 46 return true;
51 } 47 }
52 48
53 bool WebSocketExtensionParser::ConsumeExtension(WebSocketExtension* extension) { 49 bool WebSocketExtensionParser::ConsumeExtension(WebSocketExtension* extension) {
54 base::StringPiece name; 50 base::StringPiece name;
55 if (!ConsumeToken(&name)) 51 if (!ConsumeToken(&name))
56 return false; 52 return false;
57 *extension = WebSocketExtension(name.as_string()); 53 *extension = WebSocketExtension(name.as_string());
58 54
(...skipping 28 matching lines...) Expand all
87 return false; 83 return false;
88 value_string = value.as_string(); 84 value_string = value.as_string();
89 } 85 }
90 *parameter = WebSocketExtension::Parameter(name.as_string(), value_string); 86 *parameter = WebSocketExtension::Parameter(name.as_string(), value_string);
91 return true; 87 return true;
92 } 88 }
93 89
94 bool WebSocketExtensionParser::ConsumeToken(base::StringPiece* token) { 90 bool WebSocketExtensionParser::ConsumeToken(base::StringPiece* token) {
95 ConsumeSpaces(); 91 ConsumeSpaces();
96 const char* head = current_; 92 const char* head = current_;
97 while (current_ < end_ && 93 while (current_ < end_ && HttpUtil::IsTokenChar(*current_))
98 !IsControl(current_[0]) && !IsSeparator(current_[0]))
99 ++current_; 94 ++current_;
100 if (current_ == head) { 95 if (current_ == head)
101 return false; 96 return false;
102 }
103 *token = base::StringPiece(head, current_ - head); 97 *token = base::StringPiece(head, current_ - head);
104 return true; 98 return true;
105 } 99 }
106 100
107 bool WebSocketExtensionParser::ConsumeQuotedToken(std::string* token) { 101 bool WebSocketExtensionParser::ConsumeQuotedToken(std::string* token) {
108 if (!Consume('"')) 102 if (!Consume('"'))
109 return false; 103 return false;
110 104
111 *token = ""; 105 *token = "";
112 while (current_ < end_ && !IsControl(current_[0])) { 106 while (current_ < end_ && *current_ != '"') {
113 if (UnconsumedBytes() >= 2 && current_[0] == '\\') { 107 if (*current_ == '\\') {
114 char next = current_[1];
115 if (IsControl(next) || IsSeparator(next)) break;
116 *token += next;
117 current_ += 2;
118 } else if (IsSeparator(current_[0])) {
119 break;
120 } else {
121 *token += current_[0];
122 ++current_; 108 ++current_;
109 if (current_ == end_)
110 return false;
123 } 111 }
112 if (!HttpUtil::IsTokenChar(*current_))
113 return false;
114 *token += *current_;
115 ++current_;
124 } 116 }
125 // We can't use Consume here because we don't want to consume spaces. 117 if (current_ == end_)
126 if (current_ >= end_ || current_[0] != '"')
127 return false; 118 return false;
119 DCHECK_EQ(*current_, '"');
128 120
129 ++current_; 121 ++current_;
130 122
131 return !token->empty(); 123 return !token->empty();
132 } 124 }
133 125
134 void WebSocketExtensionParser::ConsumeSpaces() { 126 void WebSocketExtensionParser::ConsumeSpaces() {
135 while (current_ < end_ && (current_[0] == ' ' || current_[0] == '\t')) 127 while (current_ < end_ && (*current_ == ' ' || *current_ == '\t'))
136 ++current_; 128 ++current_;
137 return; 129 return;
138 } 130 }
139 131
140 bool WebSocketExtensionParser::Lookahead(char c) { 132 bool WebSocketExtensionParser::Lookahead(char c) {
141 const char* head = current_; 133 const char* head = current_;
142 bool result = Consume(c); 134 bool result = Consume(c);
143 current_ = head; 135 current_ = head;
144 return result; 136 return result;
145 } 137 }
146 138
147 bool WebSocketExtensionParser::ConsumeIfMatch(char c) { 139 bool WebSocketExtensionParser::ConsumeIfMatch(char c) {
148 const char* head = current_; 140 const char* head = current_;
149 if (!Consume(c)) { 141 if (!Consume(c)) {
150 current_ = head; 142 current_ = head;
151 return false; 143 return false;
152 } 144 }
153 145
154 return true; 146 return true;
155 } 147 }
156 148
157 // static
158 bool WebSocketExtensionParser::IsControl(char c) {
159 return (0 <= c && c <= 31) || c == 127;
160 }
161
162 // static
163 bool WebSocketExtensionParser::IsSeparator(char c) {
164 const char separators[] = "()<>@,;:\\\"/[]?={} \t";
165 return strchr(separators, c) != NULL;
166 }
167
168 } // namespace net 149 } // namespace net
OLDNEW
« no previous file with comments | « net/websockets/websocket_extension_parser.h ('k') | net/websockets/websocket_extension_parser_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698