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

Side by Side Diff: third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.cpp

Issue 2520223002: Replicate a parsed feature policy representation so it doesn't need to be parsed in the browser pro… (Closed)
Patch Set: Created 4 years 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "platform/feature_policy/FeaturePolicy.h" 5 #include "platform/feature_policy/FeaturePolicy.h"
6 6
7 #include "platform/json/JSONValues.h" 7 #include "platform/json/JSONValues.h"
8 #include "platform/network/HTTPParsers.h" 8 #include "platform/network/HTTPParsers.h"
9 #include "platform/weborigin/KURL.h" 9 #include "platform/weborigin/KURL.h"
10 #include "platform/weborigin/SecurityOrigin.h" 10 #include "platform/weborigin/SecurityOrigin.h"
11 #include "wtf/PtrUtil.h" 11 #include "wtf/PtrUtil.h"
12 #include "wtf/text/StringBuilder.h" 12 #include "wtf/text/StringBuilder.h"
13 13
14 namespace blink { 14 namespace blink {
15 15
16 namespace { 16 namespace {
17 17
18 // Given a string name, return the matching feature struct, or nullptr if it is 18 // Given a string name, return the matching feature struct, or nullptr if it is
19 // not the name of a policy-controlled feature. 19 // not the name of a policy-controlled feature.
20 const FeaturePolicy::Feature* featureForName( 20 const FeaturePolicy::Feature* featureForName(
21 const String& featureName, 21 const String& featureName,
22 FeaturePolicy::FeatureList& features) { 22 FeaturePolicy::FeatureList& features) {
23 for (const FeaturePolicy::Feature* feature : features) { 23 for (const FeaturePolicy::Feature* feature : features) {
24 if (featureName == feature->featureName) 24 if (featureName == feature->featureName)
25 return feature; 25 return feature;
26 } 26 }
27 return nullptr; 27 return nullptr;
28 } 28 }
29 29
30 // Converts a list of JSON feature policy items into a mapping of features to 30 WebVector<WebFeaturePolicy::ParsedWhitelist> parseFeaturePolicyFromJson(
31 // whitelists. For future compatibility, unrecognized features are simply 31 const String& policy,
32 // ignored, as are unparseable origins. If |messages| is not null, then any 32 const SecurityOrigin* origin,
33 // errors in the input will cause an error message to be appended to it. 33 Vector<String>* messages) {
34 HashMap<const FeaturePolicy::Feature*, 34 Vector<WebFeaturePolicy::ParsedWhitelist> whitelists;
35 std::unique_ptr<FeaturePolicy::Whitelist>> 35
36 parseFeaturePolicyFromJson(std::unique_ptr<JSONArray> policyItems, 36 if (origin->isUnique())
37 RefPtr<SecurityOrigin> origin, 37 return whitelists;
38 FeaturePolicy::FeatureList& features, 38
39 Vector<String>* messages) { 39 std::unique_ptr<JSONArray> policyItems = parseJSONHeader(policy);
40 HashMap<const FeaturePolicy::Feature*, 40 if (!policyItems) {
41 std::unique_ptr<FeaturePolicy::Whitelist>> 41 if (messages)
42 whitelists; 42 messages->append("Unable to parse header");
43 return whitelists;
44 }
43 45
44 for (size_t i = 0; i < policyItems->size(); ++i) { 46 for (size_t i = 0; i < policyItems->size(); ++i) {
45 JSONObject* item = JSONObject::cast(policyItems->at(i)); 47 JSONObject* item = JSONObject::cast(policyItems->at(i));
46 if (!item) { 48 if (!item) {
47 if (messages) 49 if (messages)
48 messages->append("Policy is not an object"); 50 messages->append("Policy is not an object");
49 continue; // Array element is not an object; skip 51 continue; // Array element is not an object; skip
50 } 52 }
51 53
52 for (size_t j = 0; j < item->size(); ++j) { 54 for (size_t j = 0; j < item->size(); ++j) {
53 JSONObject::Entry entry = item->at(j); 55 JSONObject::Entry entry = item->at(j);
54 String featureName = entry.first; 56 String featureName = entry.first;
55 JSONArray* targets = JSONArray::cast(entry.second); 57 JSONArray* targets = JSONArray::cast(entry.second);
56 if (!targets) { 58 if (!targets) {
57 if (messages) 59 if (messages)
58 messages->append("Whitelist is not an array of strings."); 60 messages->append("Whitelist is not an array of strings.");
59 continue; 61 continue;
60 } 62 }
61 63
62 const FeaturePolicy::Feature* feature = 64 WebFeaturePolicy::ParsedWhitelist whitelist;
63 featureForName(featureName, features); 65 whitelist.featureName = featureName;
64 if (!feature) 66 Vector<WebString> origins;
65 continue; // Feature is not recognized; skip
66
67 std::unique_ptr<FeaturePolicy::Whitelist> whitelist(
68 new FeaturePolicy::Whitelist);
69 String targetString; 67 String targetString;
70 for (size_t j = 0; j < targets->size(); ++j) { 68 for (size_t j = 0; j < targets->size(); ++j) {
71 if (targets->at(j)->asString(&targetString)) { 69 if (targets->at(j)->asString(&targetString)) {
72 if (equalIgnoringCase(targetString, "self")) { 70 if (equalIgnoringCase(targetString, "self")) {
73 whitelist->add(origin); 71 origins.append(origin->toString());
74 } else if (targetString == "*") { 72 } else if (targetString == "*") {
75 whitelist->addAll(); 73 whitelist.matchesAllOrigins = true;
76 } else { 74 } else {
77 KURL originUrl = KURL(KURL(), targetString); 75 KURL originUrl = KURL(KURL(), targetString);
78 if (originUrl.isValid()) { 76 if (originUrl.isValid())
79 whitelist->add(SecurityOrigin::create(originUrl)); 77 origins.append(targetString);
80 }
81 } 78 }
82 } else { 79 } else {
83 if (messages) 80 if (messages)
84 messages->append("Whitelist is not an array of strings."); 81 messages->append("Whitelist is not an array of strings.");
85 } 82 }
86 } 83 }
87 whitelists.set(feature, std::move(whitelist)); 84 whitelist.origins = origins;
85 whitelists.append(whitelist);
88 } 86 }
89 } 87 }
90 return whitelists; 88 return whitelists;
91 } 89 }
92 90
93 } // namespace 91 } // namespace
94 92
95 // Definitions of all features controlled by Feature Policy should appear here. 93 // Definitions of all features controlled by Feature Policy should appear here.
96 const FeaturePolicy::Feature kDocumentCookie{ 94 const FeaturePolicy::Feature kDocumentCookie{
97 "cookie", FeaturePolicy::FeatureDefault::EnableForAll}; 95 "cookie", FeaturePolicy::FeatureDefault::EnableForAll};
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 } 186 }
189 187
190 // static 188 // static
191 std::unique_ptr<FeaturePolicy> FeaturePolicy::createFromParentPolicy( 189 std::unique_ptr<FeaturePolicy> FeaturePolicy::createFromParentPolicy(
192 const FeaturePolicy* parent, 190 const FeaturePolicy* parent,
193 RefPtr<SecurityOrigin> currentOrigin) { 191 RefPtr<SecurityOrigin> currentOrigin) {
194 return createFromParentPolicy(parent, std::move(currentOrigin), 192 return createFromParentPolicy(parent, std::move(currentOrigin),
195 getDefaultFeatureList()); 193 getDefaultFeatureList());
196 } 194 }
197 195
198 void FeaturePolicy::setHeaderPolicy(const String& policy, 196 // static
199 Vector<String>* messages) { 197 WebVector<WebFeaturePolicy::ParsedWhitelist> FeaturePolicy::parseFeaturePolicy(
198 const String& policy,
199 const SecurityOrigin* origin,
200 Vector<String>* messages) {
201 return parseFeaturePolicyFromJson(policy, origin, messages);
202 }
203
204 void FeaturePolicy::setHeaderPolicy(
205 const WebVector<WebFeaturePolicy::ParsedWhitelist>& policy) {
200 DCHECK(m_headerWhitelists.isEmpty()); 206 DCHECK(m_headerWhitelists.isEmpty());
201 std::unique_ptr<JSONArray> policyJSON = parseJSONHeader(policy); 207 for (const WebFeaturePolicy::ParsedWhitelist& parsedWhitelist : policy) {
202 if (!policyJSON) { 208 const FeaturePolicy::Feature* feature =
203 if (messages) 209 featureForName(parsedWhitelist.featureName, m_features);
204 messages->append("Unable to parse header"); 210 if (!feature)
205 return; 211 continue;
212 std::unique_ptr<Whitelist> whitelist(new FeaturePolicy::Whitelist);
213 if (parsedWhitelist.matchesAllOrigins) {
214 whitelist->addAll();
215 } else {
216 for (const WebString& origin : parsedWhitelist.origins) {
217 KURL originUrl = KURL(KURL(), origin);
218 if (originUrl.isValid())
219 whitelist->add(SecurityOrigin::create(originUrl));
220 }
221 }
222 m_headerWhitelists.set(feature, std::move(whitelist));
206 } 223 }
207 m_headerWhitelists = parseFeaturePolicyFromJson(
208 std::move(policyJSON), m_origin, m_features, messages);
209 } 224 }
210 225
211 bool FeaturePolicy::isFeatureEnabledForOrigin( 226 bool FeaturePolicy::isFeatureEnabledForOrigin(
212 const FeaturePolicy::Feature& feature, 227 const FeaturePolicy::Feature& feature,
213 const SecurityOrigin& origin) const { 228 const SecurityOrigin& origin) const {
214 DCHECK(m_inheritedFeatures.contains(&feature)); 229 DCHECK(m_inheritedFeatures.contains(&feature));
215 if (!m_inheritedFeatures.get(&feature)) { 230 if (!m_inheritedFeatures.get(&feature)) {
216 return false; 231 return false;
217 } 232 }
218 if (m_headerWhitelists.contains(&feature)) { 233 if (m_headerWhitelists.contains(&feature)) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 sb.append(" "); 270 sb.append(" ");
256 sb.append(whitelist.key->featureName); 271 sb.append(whitelist.key->featureName);
257 sb.append(": "); 272 sb.append(": ");
258 sb.append(whitelist.value->toString()); 273 sb.append(whitelist.value->toString());
259 sb.append("\n"); 274 sb.append("\n");
260 } 275 }
261 return sb.toString(); 276 return sb.toString();
262 } 277 }
263 278
264 } // namespace blink 279 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698