OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
Aaron Boodman
2011/11/23 01:45:25
Shame to pull out this nice, encapsulated class an
jstritar
2011/11/28 23:09:56
Done.
| |
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/extensions/manifest_value.h" | |
6 | |
7 #include "base/basictypes.h" | |
8 #include "base/logging.h" | |
9 #include "base/string_split.h" | |
10 #include "base/values.h" | |
11 #include "chrome/common/extensions/extension_constants.h" | |
12 #include "chrome/common/extensions/extension_error_utils.h" | |
13 | |
14 namespace errors = extension_manifest_errors; | |
15 namespace keys = extension_manifest_keys; | |
16 | |
17 struct ManifestValue::FeatureRestriction { | |
18 const char* key; | |
19 const int restriction; | |
20 }; | |
21 | |
22 const ManifestValue::FeatureRestriction | |
23 ManifestValue::kFeatureRestrictions[] = { | |
24 // Base keys that all manifests can specify. | |
25 { keys::kName, kTypeAll }, | |
26 { keys::kVersion, kTypeAll }, | |
27 { keys::kManifestVersion, kTypeAll }, | |
28 { keys::kDescription, kTypeAll }, | |
29 { keys::kIcons, kTypeAll }, | |
30 { keys::kCurrentLocale, kTypeAll }, | |
31 { keys::kDefaultLocale, kTypeAll }, | |
32 { keys::kSignature, kTypeAll }, | |
33 { keys::kUpdateURL, kTypeAll }, | |
34 { keys::kPublicKey, kTypeAll }, | |
35 | |
36 // Type specific. | |
37 { keys::kApp, kTypeAllApps }, | |
38 { keys::kTheme, kTypeTheme }, | |
39 { keys::kPlatformApp, kTypePlatformApp }, | |
40 | |
41 // Extensions only. | |
42 { keys::kBrowserAction, kTypeExtension }, | |
43 { keys::kPageAction, kTypeExtension }, | |
44 { keys::kPageActions, kTypeExtension }, | |
45 { keys::kChromeURLOverrides, kTypeExtension }, | |
46 | |
47 // Hosted and packaged apps. | |
48 { keys::kPermissions, kTypeAllButThemes }, | |
49 { keys::kOptionalPermissions, kTypeAllButThemes }, | |
50 { keys::kOptionsPage, kTypeAllButThemes }, | |
51 { keys::kBackground, kTypeAllButThemes }, | |
52 { keys::kOfflineEnabled, kTypeAllButThemes }, | |
53 { keys::kMinimumChromeVersion, kTypeAllButThemes }, | |
54 { keys::kRequirements, kTypeAllButThemes }, | |
55 { keys::kConvertedFromUserScript, kTypeAllButThemes }, | |
56 | |
57 // Extensions and packaged apps. | |
58 { keys::kContentScripts, kTypeExtension | kTypePackagedApp }, | |
59 { keys::kOmnibox, kTypeExtension | kTypePackagedApp }, | |
60 { keys::kDevToolsPage, kTypeExtension | kTypePackagedApp }, | |
61 { keys::kSidebar, kTypeExtension | kTypePackagedApp }, | |
62 { keys::kHomepageURL, kTypeExtension | kTypePackagedApp }, | |
63 | |
64 // Extensions, packaged apps and platform apps. | |
65 { keys::kContentSecurityPolicy, kTypeAllApps | kTypeExtension }, | |
66 { keys::kFileBrowserHandlers, kTypeAllApps | kTypeExtension }, | |
67 { keys::kIncognito, kTypeAllApps | kTypeExtension }, | |
68 { keys::kNaClModules, kTypeAllApps | kTypeExtension }, | |
69 { keys::kPlugins, kTypeAllApps | kTypeExtension }, | |
70 { keys::kInputComponents, kTypeAllApps | kTypeExtension }, | |
71 { keys::kTtsEngine, kTypeAllApps | kTypeExtension }, | |
72 { keys::kIntents, kTypeAllApps | kTypeExtension }, | |
73 }; | |
74 | |
75 ManifestValue::ManifestValue(DictionaryValue* value) | |
76 : value_(value) { | |
77 // Read the feature restriction data. | |
78 for (size_t i = 0; i < arraysize(kFeatureRestrictions); ++i) { | |
79 restrictions_[kFeatureRestrictions[i].key] = | |
Aaron Boodman
2011/11/23 01:45:25
Sucks to have a separate copy of this for every in
jstritar
2011/11/28 23:09:56
Done.. LazyInstance is sweet!
| |
80 kFeatureRestrictions[i].restriction; | |
81 } | |
82 | |
83 // Determine what type of extension the manifest represents. | |
84 if (IsTheme()) | |
Aaron Boodman
2011/11/23 01:45:25
Consider omitting the type_ member and instead hav
jstritar
2011/11/28 23:09:56
Done.
| |
85 type_ = kTypeTheme; | |
86 else if (IsPlatformApp()) | |
87 type_ = kTypePlatformApp; | |
88 else if (IsHostedApp()) | |
89 type_ = kTypeHostedApp; | |
90 else if (IsPackagedApp()) | |
91 type_ = kTypePackagedApp; | |
92 else | |
93 type_ = kTypeExtension; | |
94 } | |
95 | |
96 ManifestValue::~ManifestValue() {} | |
97 | |
98 bool ManifestValue::ValidateManifest(std::string* error) const { | |
99 for (DictionaryValue::key_iterator key = value_->begin_keys(); | |
100 key != value_->end_keys(); ++key) { | |
101 // When validating the extension manifests, we ignore keys that are not | |
102 // recognized for compatibility. | |
Aaron Boodman
2011/11/23 01:45:25
For clarity: s/for compatibility/for forward compa
jstritar
2011/11/28 23:09:56
Done.
| |
103 if (!IsKnownKey(*key)) | |
Aaron Boodman
2011/11/23 01:45:25
Add:
TODO(aa): Consider having an error here in t
jstritar
2011/11/28 23:09:56
Done.
| |
104 continue; | |
105 | |
106 if (!CanAccessKey(*key)) { | |
Aaron Boodman
2011/11/23 01:45:25
I think that there will probably be legacy data he
jstritar
2011/11/28 23:09:56
I think we're okay here because we parsed hosted a
| |
107 *error = ExtensionErrorUtils::FormatErrorMessage( | |
108 errors::kFeatureNotAllowed, *key); | |
109 return false; | |
110 } | |
111 } | |
112 | |
113 return true; | |
114 } | |
115 | |
116 bool ManifestValue::HasKey(const std::string& key) const { | |
117 // Return false instead of CHECKing, since we're just testing for existence. | |
118 return CanAccessKey(key) && value_->HasKey(key); | |
119 } | |
120 | |
121 bool ManifestValue::Get( | |
122 const std::string& path, Value** out_value) const { | |
123 CHECK(CanAccessPath(path)) << path; | |
124 return value_->Get(path, out_value); | |
125 } | |
126 | |
127 bool ManifestValue::GetBoolean( | |
128 const std::string& path, bool* out_value) const { | |
129 CHECK(CanAccessPath(path)) << path; | |
130 return value_->GetBoolean(path, out_value); | |
131 } | |
132 | |
133 bool ManifestValue::GetInteger( | |
134 const std::string& path, int* out_value) const { | |
135 CHECK(CanAccessPath(path)) << path; | |
136 return value_->GetInteger(path, out_value); | |
137 } | |
138 | |
139 bool ManifestValue::GetString( | |
140 const std::string& path, std::string* out_value) const { | |
141 CHECK(CanAccessPath(path)) << path; | |
142 return value_->GetString(path, out_value); | |
143 } | |
144 | |
145 bool ManifestValue::GetString( | |
146 const std::string& path, string16* out_value) const { | |
147 CHECK(CanAccessPath(path)) << path; | |
148 return value_->GetString(path, out_value); | |
149 } | |
150 | |
151 bool ManifestValue::GetDictionary( | |
152 const std::string& path, DictionaryValue** out_value) const { | |
153 CHECK(CanAccessPath(path)) << path; | |
154 return value_->GetDictionary(path, out_value); | |
155 } | |
156 | |
157 bool ManifestValue::GetList( | |
158 const std::string& path, ListValue** out_value) const { | |
159 CHECK(CanAccessPath(path)) << path; | |
160 return value_->GetList(path, out_value); | |
161 } | |
162 | |
163 ManifestValue* ManifestValue::DeepCopy() const { | |
164 return new ManifestValue(value_->DeepCopy()); | |
165 } | |
166 | |
167 bool ManifestValue::Equals(const ManifestValue* other) const { | |
168 return other && value_->Equals(other->value()); | |
169 } | |
170 | |
171 bool ManifestValue::IsTheme() const { | |
172 DictionaryValue* dict_value = NULL; | |
173 return value_->HasKey(keys::kTheme) && | |
174 value_->GetDictionary(keys::kTheme, &dict_value); | |
175 } | |
176 | |
177 bool ManifestValue::IsPlatformApp() const { | |
178 return value_->HasKey(keys::kPlatformApp); | |
179 } | |
180 | |
181 bool ManifestValue::IsPackagedApp() const { | |
182 return value_->HasKey(keys::kApp) && !value_->HasKey(keys::kWebURLs); | |
183 } | |
184 | |
185 bool ManifestValue::IsHostedApp() const { | |
186 return value_->HasKey(keys::kApp) && value_->HasKey(keys::kWebURLs); | |
187 } | |
188 | |
189 bool ManifestValue::IsKnownKey(const std::string& key) const { | |
190 RestrictionMap::const_iterator i = restrictions_.find(key); | |
191 return i != restrictions_.end(); | |
192 } | |
193 | |
194 bool ManifestValue::CanAccessKey(const std::string& key) const { | |
195 RestrictionMap::const_iterator i = restrictions_.find(key); | |
196 return (i != restrictions_.end() && (type_ & i->second) != 0); | |
197 } | |
198 | |
199 bool ManifestValue::CanAccessPath(const std::string& path) const { | |
200 std::vector<std::string> components; | |
201 base::SplitString(path, '.', &components); | |
202 return CanAccessKey(components[0]); | |
203 } | |
OLD | NEW |