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

Side by Side Diff: chrome/common/content_settings_pattern_parser.cc

Issue 518803009: Move content_settings_pattern and content_settings_pattern_parser to the content_settings component. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 6 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
(Empty)
1 // Copyright (c) 2012 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.
4
5 #include "chrome/common/content_settings_pattern_parser.h"
6
7 #include "base/strings/string_util.h"
8 #include "url/url_constants.h"
9
10 namespace {
11
12 const char kDomainWildcard[] = "[*.]";
13 const size_t kDomainWildcardLength = 4;
14 const char kHostWildcard[] = "*";
15 const char kPathWildcard[] = "*";
16 const char kPortWildcard[] = "*";
17 const char kSchemeWildcard[] = "*";
18 const char kUrlPathSeparator[] = "/";
19 const char kUrlPortSeparator[] = ":";
20
21 class Component {
22 public:
23 Component() : start(0), len(0) {}
24 Component(size_t s, size_t l) : start(s), len(l) {}
25
26 bool IsNonEmpty() {
27 return len > 0;
28 }
29
30 size_t start;
31 size_t len;
32 };
33
34 } // namespace
35
36 namespace content_settings {
37
38 void PatternParser::Parse(const std::string& pattern_spec,
39 ContentSettingsPattern::BuilderInterface* builder) {
40 if (pattern_spec == "*") {
41 builder->WithSchemeWildcard();
42 builder->WithDomainWildcard();
43 builder->WithPortWildcard();
44 return;
45 }
46
47 // Initialize components for the individual patterns parts to empty
48 // sub-strings.
49 Component scheme_component;
50 Component host_component;
51 Component port_component;
52 Component path_component;
53
54 size_t start = 0;
55 size_t current_pos = 0;
56
57 if (pattern_spec.empty())
58 return;
59
60 // Test if a scheme pattern is in the spec.
61 const std::string standard_scheme_separator(url::kStandardSchemeSeparator);
62 current_pos = pattern_spec.find(standard_scheme_separator, start);
63 if (current_pos != std::string::npos) {
64 scheme_component = Component(start, current_pos);
65 start = current_pos + standard_scheme_separator.size();
66 current_pos = start;
67 } else {
68 current_pos = start;
69 }
70
71 if (start >= pattern_spec.size())
72 return; // Bad pattern spec.
73
74 // Jump to the end of domain wildcards or an IPv6 addresses. IPv6 addresses
75 // contain ':'. So first move to the end of an IPv6 address befor searching
76 // for the ':' that separates the port form the host.
77 if (pattern_spec[current_pos] == '[')
78 current_pos = pattern_spec.find("]", start);
79
80 if (current_pos == std::string::npos)
81 return; // Bad pattern spec.
82
83 current_pos = pattern_spec.find(std::string(kUrlPortSeparator), current_pos);
84 if (current_pos == std::string::npos) {
85 // No port spec found
86 current_pos = pattern_spec.find(std::string(kUrlPathSeparator), start);
87 if (current_pos == std::string::npos) {
88 current_pos = pattern_spec.size();
89 host_component = Component(start, current_pos - start);
90 } else {
91 // Pattern has a path spec.
92 host_component = Component(start, current_pos - start);
93 }
94 start = current_pos;
95 } else {
96 // Port spec found.
97 host_component = Component(start, current_pos - start);
98 start = current_pos + 1;
99 if (start < pattern_spec.size()) {
100 current_pos = pattern_spec.find(std::string(kUrlPathSeparator), start);
101 if (current_pos == std::string::npos) {
102 current_pos = pattern_spec.size();
103 }
104 port_component = Component(start, current_pos - start);
105 start = current_pos;
106 }
107 }
108
109 current_pos = pattern_spec.size();
110 if (start < current_pos) {
111 // Pattern has a path spec.
112 path_component = Component(start, current_pos - start);
113 }
114
115 // Set pattern parts.
116 std::string scheme;
117 if (scheme_component.IsNonEmpty()) {
118 scheme = pattern_spec.substr(scheme_component.start, scheme_component.len);
119 if (scheme == kSchemeWildcard) {
120 builder->WithSchemeWildcard();
121 } else {
122 builder->WithScheme(scheme);
123 }
124 } else {
125 builder->WithSchemeWildcard();
126 }
127
128 if (host_component.IsNonEmpty()) {
129 std::string host = pattern_spec.substr(host_component.start,
130 host_component.len);
131 if (host == kHostWildcard) {
132 builder->WithDomainWildcard();
133 } else if (StartsWithASCII(host, kDomainWildcard, true)) {
134 host = host.substr(kDomainWildcardLength);
135 builder->WithDomainWildcard();
136 builder->WithHost(host);
137 } else {
138 // If the host contains a wildcard symbol then it is invalid.
139 if (host.find(kHostWildcard) != std::string::npos) {
140 builder->Invalid();
141 return;
142 }
143 builder->WithHost(host);
144 }
145 }
146
147 if (port_component.IsNonEmpty()) {
148 const std::string port = pattern_spec.substr(port_component.start,
149 port_component.len);
150 if (port == kPortWildcard) {
151 builder->WithPortWildcard();
152 } else {
153 // Check if the port string represents a valid port.
154 for (size_t i = 0; i < port.size(); ++i) {
155 if (!IsAsciiDigit(port[i])) {
156 builder->Invalid();
157 return;
158 }
159 }
160 // TODO(markusheintz): Check port range.
161 builder->WithPort(port);
162 }
163 } else {
164 if (!ContentSettingsPattern::IsNonWildcardDomainNonPortScheme(scheme) &&
165 scheme != url::kFileScheme)
166 builder->WithPortWildcard();
167 }
168
169 if (path_component.IsNonEmpty()) {
170 const std::string path = pattern_spec.substr(path_component.start,
171 path_component.len);
172 if (path.substr(1) == kPathWildcard)
173 builder->WithPathWildcard();
174 else
175 builder->WithPath(path);
176 }
177 }
178
179 // static
180 std::string PatternParser::ToString(
181 const ContentSettingsPattern::PatternParts& parts) {
182 // Return the most compact form to support legacy code and legacy pattern
183 // strings.
184 if (parts.is_scheme_wildcard &&
185 parts.has_domain_wildcard &&
186 parts.host.empty() &&
187 parts.is_port_wildcard)
188 return "*";
189
190 std::string str;
191 if (!parts.is_scheme_wildcard)
192 str += parts.scheme + url::kStandardSchemeSeparator;
193
194 if (parts.scheme == url::kFileScheme) {
195 if (parts.is_path_wildcard)
196 return str + kUrlPathSeparator + kPathWildcard;
197 else
198 return str + parts.path;
199 }
200
201 if (parts.has_domain_wildcard) {
202 if (parts.host.empty())
203 str += kHostWildcard;
204 else
205 str += kDomainWildcard;
206 }
207 str += parts.host;
208
209 if (ContentSettingsPattern::IsNonWildcardDomainNonPortScheme(parts.scheme)) {
210 str += parts.path.empty() ? std::string(kUrlPathSeparator) : parts.path;
211 return str;
212 }
213
214 if (!parts.is_port_wildcard) {
215 str += std::string(kUrlPortSeparator) + parts.port;
216 }
217
218 return str;
219 }
220
221 } // namespace content_settings
OLDNEW
« no previous file with comments | « chrome/common/content_settings_pattern_parser.h ('k') | chrome/common/content_settings_pattern_parser_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698