OLD | NEW |
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/RuntimeEnabledFeatures.h" | 7 #include "platform/RuntimeEnabledFeatures.h" |
8 #include "platform/json/JSONValues.h" | 8 #include "platform/json/JSONValues.h" |
9 #include "platform/network/HTTPParsers.h" | 9 #include "platform/network/HTTPParsers.h" |
10 #include "platform/weborigin/SecurityOrigin.h" | 10 #include "platform/weborigin/SecurityOrigin.h" |
11 #include "platform/wtf/PtrUtil.h" | 11 #include "platform/wtf/PtrUtil.h" |
12 | 12 |
13 namespace blink { | 13 namespace blink { |
14 | 14 |
15 WebFeaturePolicyFeature GetWebFeaturePolicyFeature(const String& feature) { | 15 WebParsedFeaturePolicy ParseFeaturePolicy(const String& policy, |
16 if (feature == "fullscreen") | 16 RefPtr<SecurityOrigin> origin, |
17 return WebFeaturePolicyFeature::kFullscreen; | 17 Vector<String>* messages) { |
18 if (feature == "payment") | 18 return ParseFeaturePolicy(policy, origin, messages, |
19 return WebFeaturePolicyFeature::kPayment; | 19 GetDefaultFeatureNameMap()); |
20 if (feature == "vibrate") | |
21 return WebFeaturePolicyFeature::kVibrate; | |
22 if (RuntimeEnabledFeatures::featurePolicyExperimentalFeaturesEnabled()) { | |
23 if (feature == "camera") | |
24 return WebFeaturePolicyFeature::kCamera; | |
25 if (feature == "eme") | |
26 return WebFeaturePolicyFeature::kEme; | |
27 if (feature == "microphone") | |
28 return WebFeaturePolicyFeature::kMicrophone; | |
29 if (feature == "speaker") | |
30 return WebFeaturePolicyFeature::kSpeaker; | |
31 if (feature == "cookie") | |
32 return WebFeaturePolicyFeature::kDocumentCookie; | |
33 if (feature == "domain") | |
34 return WebFeaturePolicyFeature::kDocumentDomain; | |
35 if (feature == "docwrite") | |
36 return WebFeaturePolicyFeature::kDocumentWrite; | |
37 if (feature == "geolocation") | |
38 return WebFeaturePolicyFeature::kGeolocation; | |
39 if (feature == "midi") | |
40 return WebFeaturePolicyFeature::kMidiFeature; | |
41 if (feature == "notifications") | |
42 return WebFeaturePolicyFeature::kNotifications; | |
43 if (feature == "push") | |
44 return WebFeaturePolicyFeature::kPush; | |
45 if (feature == "sync-script") | |
46 return WebFeaturePolicyFeature::kSyncScript; | |
47 if (feature == "sync-xhr") | |
48 return WebFeaturePolicyFeature::kSyncXHR; | |
49 if (feature == "webrtc") | |
50 return WebFeaturePolicyFeature::kWebRTC; | |
51 } | |
52 return WebFeaturePolicyFeature::kNotFound; | |
53 } | 20 } |
54 | 21 |
55 WebParsedFeaturePolicy ParseFeaturePolicy(const String& policy, | 22 WebParsedFeaturePolicy ParseFeaturePolicy(const String& policy, |
56 RefPtr<SecurityOrigin> origin, | 23 RefPtr<SecurityOrigin> origin, |
57 Vector<String>* messages) { | 24 Vector<String>* messages, |
| 25 const FeatureNameMap& feature_names) { |
58 Vector<WebParsedFeaturePolicyDeclaration> whitelists; | 26 Vector<WebParsedFeaturePolicyDeclaration> whitelists; |
59 | 27 |
60 // Use a reasonable parse depth limit; the actual maximum depth is only going | 28 // Use a reasonable parse depth limit; the actual maximum depth is only going |
61 // to be 4 for a valid policy, but we'll give the featurePolicyParser a chance | 29 // to be 4 for a valid policy, but we'll give the featurePolicyParser a chance |
62 // to report more specific errors, unless the string is really invalid. | 30 // to report more specific errors, unless the string is really invalid. |
63 std::unique_ptr<JSONArray> policy_items = ParseJSONHeader(policy, 50); | 31 std::unique_ptr<JSONArray> policy_items = ParseJSONHeader(policy, 50); |
64 if (!policy_items) { | 32 if (!policy_items) { |
65 if (messages) | 33 if (messages) |
66 messages->push_back("Unable to parse header."); | 34 messages->push_back("Unable to parse header."); |
67 return whitelists; | 35 return whitelists; |
68 } | 36 } |
69 | 37 |
70 for (size_t i = 0; i < policy_items->size(); ++i) { | 38 for (size_t i = 0; i < policy_items->size(); ++i) { |
71 JSONObject* item = JSONObject::Cast(policy_items->at(i)); | 39 JSONObject* item = JSONObject::Cast(policy_items->at(i)); |
72 if (!item) { | 40 if (!item) { |
73 if (messages) | 41 if (messages) |
74 messages->push_back("Policy is not an object."); | 42 messages->push_back("Policy is not an object."); |
75 continue; // Array element is not an object; skip | 43 continue; // Array element is not an object; skip |
76 } | 44 } |
77 | 45 |
78 for (size_t j = 0; j < item->size(); ++j) { | 46 for (size_t j = 0; j < item->size(); ++j) { |
79 JSONObject::Entry entry = item->at(j); | 47 JSONObject::Entry entry = item->at(j); |
80 WebFeaturePolicyFeature feature = GetWebFeaturePolicyFeature(entry.first); | 48 if (!feature_names.Contains(entry.first)) |
81 if (feature == WebFeaturePolicyFeature::kNotFound) | |
82 continue; // Unrecognized feature; skip | 49 continue; // Unrecognized feature; skip |
| 50 WebFeaturePolicyFeature feature = feature_names.at(entry.first); |
83 JSONArray* targets = JSONArray::Cast(entry.second); | 51 JSONArray* targets = JSONArray::Cast(entry.second); |
84 if (!targets) { | 52 if (!targets) { |
85 if (messages) | 53 if (messages) |
86 messages->push_back("Whitelist is not an array of strings."); | 54 messages->push_back("Whitelist is not an array of strings."); |
87 continue; | 55 continue; |
88 } | 56 } |
89 | 57 |
90 WebParsedFeaturePolicyDeclaration whitelist; | 58 WebParsedFeaturePolicyDeclaration whitelist; |
91 whitelist.feature = feature; | 59 whitelist.feature = feature; |
92 Vector<WebSecurityOrigin> origins; | 60 Vector<WebSecurityOrigin> origins; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 Vector<WebParsedFeaturePolicyDeclaration> whitelists; | 92 Vector<WebParsedFeaturePolicyDeclaration> whitelists; |
125 for (const WebFeaturePolicyFeature feature : features) { | 93 for (const WebFeaturePolicyFeature feature : features) { |
126 WebParsedFeaturePolicyDeclaration whitelist; | 94 WebParsedFeaturePolicyDeclaration whitelist; |
127 whitelist.feature = feature; | 95 whitelist.feature = feature; |
128 whitelist.origins = Vector<WebSecurityOrigin>(1UL, {origin}); | 96 whitelist.origins = Vector<WebSecurityOrigin>(1UL, {origin}); |
129 whitelists.push_back(whitelist); | 97 whitelists.push_back(whitelist); |
130 } | 98 } |
131 return whitelists; | 99 return whitelists; |
132 } | 100 } |
133 | 101 |
| 102 const FeatureNameMap& GetDefaultFeatureNameMap() { |
| 103 DEFINE_STATIC_LOCAL(FeatureNameMap, default_feature_name_map, ()); |
| 104 if (default_feature_name_map.IsEmpty()) { |
| 105 default_feature_name_map.Set("fullscreen", |
| 106 WebFeaturePolicyFeature::kFullscreen); |
| 107 default_feature_name_map.Set("payment", WebFeaturePolicyFeature::kPayment); |
| 108 if (RuntimeEnabledFeatures::featurePolicyExperimentalFeaturesEnabled()) { |
| 109 default_feature_name_map.Set("vibrate", |
| 110 WebFeaturePolicyFeature::kVibrate); |
| 111 default_feature_name_map.Set("camera", WebFeaturePolicyFeature::kCamera); |
| 112 default_feature_name_map.Set("eme", WebFeaturePolicyFeature::kEme); |
| 113 default_feature_name_map.Set("microphone", |
| 114 WebFeaturePolicyFeature::kMicrophone); |
| 115 default_feature_name_map.Set("speaker", |
| 116 WebFeaturePolicyFeature::kSpeaker); |
| 117 default_feature_name_map.Set("cookie", |
| 118 WebFeaturePolicyFeature::kDocumentCookie); |
| 119 default_feature_name_map.Set("domain", |
| 120 WebFeaturePolicyFeature::kDocumentDomain); |
| 121 default_feature_name_map.Set("docwrit", |
| 122 WebFeaturePolicyFeature::kDocumentWrite); |
| 123 default_feature_name_map.Set("geolocation", |
| 124 WebFeaturePolicyFeature::kGeolocation); |
| 125 default_feature_name_map.Set("midi", |
| 126 WebFeaturePolicyFeature::kMidiFeature); |
| 127 default_feature_name_map.Set("notifications", |
| 128 WebFeaturePolicyFeature::kNotifications); |
| 129 default_feature_name_map.Set("push", WebFeaturePolicyFeature::kPush); |
| 130 default_feature_name_map.Set("sync-script", |
| 131 WebFeaturePolicyFeature::kSyncScript); |
| 132 default_feature_name_map.Set("sync-xhr", |
| 133 WebFeaturePolicyFeature::kSyncXHR); |
| 134 default_feature_name_map.Set("webrtc", WebFeaturePolicyFeature::kWebRTC); |
| 135 } |
| 136 } |
| 137 return default_feature_name_map; |
| 138 } |
| 139 |
134 } // namespace blink | 140 } // namespace blink |
OLD | NEW |