Check USB device path access when prompting users to select a device.
[chromium-blink-merge.git] / net / websockets / websocket_extension_parser.cc
blob109d330c3a1ff8e5f2396e3573177c79a03017b9
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
3 // found in the LICENSE file.
5 #include "net/websockets/websocket_extension_parser.h"
7 #include "base/strings/string_util.h"
9 namespace net {
11 WebSocketExtensionParser::WebSocketExtensionParser() {}
13 WebSocketExtensionParser::~WebSocketExtensionParser() {}
15 void WebSocketExtensionParser::Parse(const char* data, size_t size) {
16 current_ = data;
17 end_ = data + size;
18 has_error_ = false;
19 extensions_.clear();
21 while (true) {
22 WebSocketExtension extension;
23 ConsumeExtension(&extension);
24 if (has_error_)
25 break;
26 extensions_.push_back(extension);
28 ConsumeSpaces();
29 DCHECK(!has_error_);
31 if (!ConsumeIfMatch(',')) {
32 break;
36 has_error_ = has_error_ || current_ != end_;
37 if (has_error_)
38 extensions_.clear();
41 void WebSocketExtensionParser::Consume(char c) {
42 DCHECK(!has_error_);
43 ConsumeSpaces();
44 DCHECK(!has_error_);
45 if (current_ == end_ || c != current_[0]) {
46 has_error_ = true;
47 return;
49 ++current_;
52 void WebSocketExtensionParser::ConsumeExtension(WebSocketExtension* extension) {
53 DCHECK(!has_error_);
54 base::StringPiece name;
55 ConsumeToken(&name);
56 if (has_error_) return;
57 *extension = WebSocketExtension(name.as_string());
59 while (ConsumeIfMatch(';')) {
60 WebSocketExtension::Parameter parameter((std::string()));
61 ConsumeExtensionParameter(&parameter);
62 if (has_error_) return;
63 extension->Add(parameter);
67 void WebSocketExtensionParser::ConsumeExtensionParameter(
68 WebSocketExtension::Parameter* parameter) {
69 DCHECK(!has_error_);
70 base::StringPiece name, value;
71 std::string value_string;
73 ConsumeToken(&name);
74 if (has_error_) return;
75 if (!ConsumeIfMatch('=')) {
76 *parameter = WebSocketExtension::Parameter(name.as_string());
77 return;
80 if (Lookahead('\"')) {
81 ConsumeQuotedToken(&value_string);
82 } else {
83 ConsumeToken(&value);
84 value_string = value.as_string();
86 if (has_error_) return;
87 *parameter = WebSocketExtension::Parameter(name.as_string(), value_string);
90 void WebSocketExtensionParser::ConsumeToken(base::StringPiece* token) {
91 DCHECK(!has_error_);
92 ConsumeSpaces();
93 DCHECK(!has_error_);
94 const char* head = current_;
95 while (current_ < end_ &&
96 !IsControl(current_[0]) && !IsSeparator(current_[0]))
97 ++current_;
98 if (current_ == head) {
99 has_error_ = true;
100 return;
102 *token = base::StringPiece(head, current_ - head);
105 void WebSocketExtensionParser::ConsumeQuotedToken(std::string* token) {
106 DCHECK(!has_error_);
107 Consume('"');
108 if (has_error_) return;
109 *token = "";
110 while (current_ < end_ && !IsControl(current_[0])) {
111 if (UnconsumedBytes() >= 2 && current_[0] == '\\') {
112 char next = current_[1];
113 if (IsControl(next) || IsSeparator(next)) break;
114 *token += next;
115 current_ += 2;
116 } else if (IsSeparator(current_[0])) {
117 break;
118 } else {
119 *token += current_[0];
120 ++current_;
123 // We can't use Consume here because we don't want to consume spaces.
124 if (current_ < end_ && current_[0] == '"')
125 ++current_;
126 else
127 has_error_ = true;
128 has_error_ = has_error_ || token->empty();
131 void WebSocketExtensionParser::ConsumeSpaces() {
132 DCHECK(!has_error_);
133 while (current_ < end_ && (current_[0] == ' ' || current_[0] == '\t'))
134 ++current_;
135 return;
138 bool WebSocketExtensionParser::Lookahead(char c) {
139 DCHECK(!has_error_);
140 const char* head = current_;
142 Consume(c);
143 bool result = !has_error_;
144 current_ = head;
145 has_error_ = false;
146 return result;
149 bool WebSocketExtensionParser::ConsumeIfMatch(char c) {
150 DCHECK(!has_error_);
151 const char* head = current_;
153 Consume(c);
154 if (has_error_) {
155 current_ = head;
156 has_error_ = false;
157 return false;
159 return true;
162 // static
163 bool WebSocketExtensionParser::IsControl(char c) {
164 return (0 <= c && c <= 31) || c == 127;
167 // static
168 bool WebSocketExtensionParser::IsSeparator(char c) {
169 const char separators[] = "()<>@,;:\\\"/[]?={} \t";
170 return strchr(separators, c) != NULL;
173 } // namespace net