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

Side by Side Diff: chrome/common/extensions/extension.cc

Issue 8654001: Reland restrict extension features based on the extension type. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 9 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "chrome/common/extensions/extension.h" 5 #include "chrome/common/extensions/extension.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/base64.h" 9 #include "base/base64.h"
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
(...skipping 15 matching lines...) Expand all
26 #include "chrome/common/chrome_switches.h" 26 #include "chrome/common/chrome_switches.h"
27 #include "chrome/common/chrome_version_info.h" 27 #include "chrome/common/chrome_version_info.h"
28 #include "chrome/common/extensions/extension_action.h" 28 #include "chrome/common/extensions/extension_action.h"
29 #include "chrome/common/extensions/extension_constants.h" 29 #include "chrome/common/extensions/extension_constants.h"
30 #include "chrome/common/extensions/extension_error_utils.h" 30 #include "chrome/common/extensions/extension_error_utils.h"
31 #include "chrome/common/extensions/extension_l10n_util.h" 31 #include "chrome/common/extensions/extension_l10n_util.h"
32 #include "chrome/common/extensions/extension_resource.h" 32 #include "chrome/common/extensions/extension_resource.h"
33 #include "chrome/common/extensions/extension_sidebar_defaults.h" 33 #include "chrome/common/extensions/extension_sidebar_defaults.h"
34 #include "chrome/common/extensions/extension_sidebar_utils.h" 34 #include "chrome/common/extensions/extension_sidebar_utils.h"
35 #include "chrome/common/extensions/file_browser_handler.h" 35 #include "chrome/common/extensions/file_browser_handler.h"
36 #include "chrome/common/extensions/manifest_value.h"
36 #include "chrome/common/extensions/user_script.h" 37 #include "chrome/common/extensions/user_script.h"
37 #include "chrome/common/url_constants.h" 38 #include "chrome/common/url_constants.h"
38 #include "googleurl/src/url_util.h" 39 #include "googleurl/src/url_util.h"
39 #include "grit/chromium_strings.h" 40 #include "grit/chromium_strings.h"
40 #include "grit/generated_resources.h" 41 #include "grit/generated_resources.h"
41 #include "grit/theme_resources.h" 42 #include "grit/theme_resources.h"
42 #include "net/base/registry_controlled_domain.h" 43 #include "net/base/registry_controlled_domain.h"
43 #include "third_party/skia/include/core/SkBitmap.h" 44 #include "third_party/skia/include/core/SkBitmap.h"
44 #include "ui/base/l10n/l10n_util.h" 45 #include "ui/base/l10n/l10n_util.h"
45 #include "ui/base/resource/resource_bundle.h" 46 #include "ui/base/resource/resource_bundle.h"
(...skipping 27 matching lines...) Expand all
73 static void ConvertHexadecimalToIDAlphabet(std::string* id) { 74 static void ConvertHexadecimalToIDAlphabet(std::string* id) {
74 for (size_t i = 0; i < id->size(); ++i) { 75 for (size_t i = 0; i < id->size(); ++i) {
75 int val; 76 int val;
76 if (base::HexStringToInt(id->begin() + i, id->begin() + i + 1, &val)) 77 if (base::HexStringToInt(id->begin() + i, id->begin() + i + 1, &val))
77 (*id)[i] = val + 'a'; 78 (*id)[i] = val + 'a';
78 else 79 else
79 (*id)[i] = 'a'; 80 (*id)[i] = 'a';
80 } 81 }
81 } 82 }
82 83
83 // These keys are allowed by all crx files (apps, extensions, themes, etc).
84 static const char* kBaseCrxKeys[] = {
85 keys::kCurrentLocale,
86 keys::kDefaultLocale,
87 keys::kDescription,
88 keys::kIcons,
89 keys::kName,
90 keys::kPublicKey,
91 keys::kSignature,
92 keys::kVersion,
93 keys::kUpdateURL
94 };
95
96 bool IsBaseCrxKey(const std::string& key) {
97 for (size_t i = 0; i < arraysize(kBaseCrxKeys); ++i) {
98 if (key == kBaseCrxKeys[i])
99 return true;
100 }
101
102 return false;
103 }
104
105 // A singleton object containing global data needed by the extension objects. 84 // A singleton object containing global data needed by the extension objects.
106 class ExtensionConfig { 85 class ExtensionConfig {
107 public: 86 public:
108 static ExtensionConfig* GetInstance() { 87 static ExtensionConfig* GetInstance() {
109 return Singleton<ExtensionConfig>::get(); 88 return Singleton<ExtensionConfig>::get();
110 } 89 }
111 90
112 Extension::ScriptingWhitelist* whitelist() { return &scripting_whitelist_; } 91 Extension::ScriptingWhitelist* whitelist() { return &scripting_whitelist_; }
113 92
114 private: 93 private:
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 219
241 // static 220 // static
242 scoped_refptr<Extension> Extension::Create(const FilePath& path, 221 scoped_refptr<Extension> Extension::Create(const FilePath& path,
243 Location location, 222 Location location,
244 const DictionaryValue& value, 223 const DictionaryValue& value,
245 int flags, 224 int flags,
246 std::string* error) { 225 std::string* error) {
247 DCHECK(error); 226 DCHECK(error);
248 scoped_refptr<Extension> extension = new Extension(path, location); 227 scoped_refptr<Extension> extension = new Extension(path, location);
249 228
250 if (!extension->InitFromValue(value, flags, error)) 229 if (!extension->InitFromValue(ManifestValue(value.DeepCopy()), flags, error))
Aaron Boodman 2011/11/23 01:45:25 This kinda sucks, we end up copying this same Dict
jstritar 2011/11/28 23:09:56 Done, we only copy the DictionaryValue once now.
251 return NULL; 230 return NULL;
252 return extension; 231 return extension;
253 } 232 }
254 233
255 scoped_refptr<Extension> Extension::CreateWithId(const FilePath& path, 234 scoped_refptr<Extension> Extension::CreateWithId(const FilePath& path,
256 Location location, 235 Location location,
257 const DictionaryValue& value, 236 const DictionaryValue& value,
258 int flags, 237 int flags,
259 const std::string& explicit_id, 238 const std::string& explicit_id,
260 std::string* error) { 239 std::string* error) {
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after
885 GURL url = extension_sidebar_utils::ResolveRelativePath( 864 GURL url = extension_sidebar_utils::ResolveRelativePath(
886 default_page, this, error); 865 default_page, this, error);
887 if (!url.is_valid()) 866 if (!url.is_valid())
888 return NULL; 867 return NULL;
889 result->set_default_page(url); 868 result->set_default_page(url);
890 } 869 }
891 870
892 return result.release(); 871 return result.release();
893 } 872 }
894 873
895 bool Extension::ContainsNonThemeKeys(const DictionaryValue& source) const { 874 bool Extension::LoadIsApp(const ManifestValue* manifest,
896 for (DictionaryValue::key_iterator key = source.begin_keys();
897 key != source.end_keys(); ++key) {
898 if (!IsBaseCrxKey(*key) && *key != keys::kTheme)
899 return true;
900 }
901 return false;
902 }
903
904 bool Extension::LoadIsApp(const DictionaryValue* manifest,
905 std::string* error) { 875 std::string* error) {
906 if (manifest->HasKey(keys::kApp)) 876 is_app_ = manifest->HasKey(keys::kApp);
Aaron Boodman 2011/11/23 01:45:25 Can you get rid of all the is_*_ members in Extens
jstritar 2011/11/28 23:09:56 Done.
907 is_app_ = true;
908 877
909 if (CommandLine::ForCurrentProcess()->HasSwitch( 878 if (CommandLine::ForCurrentProcess()->HasSwitch(
910 switches::kEnablePlatformApps)) { 879 switches::kEnablePlatformApps))
911 if (manifest->HasKey(keys::kPlatformApp)) 880 is_platform_app_ = manifest->HasKey(keys::kPlatformApp);
912 is_platform_app_ = true;
913 }
914 881
915 return true; 882 return true;
916 } 883 }
917 884
918 bool Extension::LoadExtent(const DictionaryValue* manifest, 885 bool Extension::LoadExtent(const ManifestValue* manifest,
919 const char* key, 886 const char* key,
920 URLPatternSet* extent, 887 URLPatternSet* extent,
921 const char* list_error, 888 const char* list_error,
922 const char* value_error, 889 const char* value_error,
923 URLPattern::ParseOption parse_strictness, 890 URLPattern::ParseOption parse_strictness,
924 std::string* error) { 891 std::string* error) {
925 Value* temp = NULL; 892 Value* temp = NULL;
926 if (!manifest->Get(key, &temp)) 893 if (!manifest->Get(key, &temp))
927 return true; 894 return true;
928 895
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 return false; 952 return false;
986 } 953 }
987 pattern.SetPath(pattern.path() + '*'); 954 pattern.SetPath(pattern.path() + '*');
988 955
989 extent->AddPattern(pattern); 956 extent->AddPattern(pattern);
990 } 957 }
991 958
992 return true; 959 return true;
993 } 960 }
994 961
995 bool Extension::LoadLaunchURL(const DictionaryValue* manifest, 962 bool Extension::LoadLaunchURL(const ManifestValue* manifest,
996 std::string* error) { 963 std::string* error) {
997 Value* temp = NULL; 964 Value* temp = NULL;
998 965
999 // launch URL can be either local (to chrome-extension:// root) or an absolute 966 // launch URL can be either local (to chrome-extension:// root) or an absolute
1000 // web URL. 967 // web URL.
1001 if (manifest->Get(keys::kLaunchLocalPath, &temp)) { 968 if (manifest->Get(keys::kLaunchLocalPath, &temp)) {
1002 if (manifest->Get(keys::kLaunchWebURL, NULL)) { 969 if (manifest->Get(keys::kLaunchWebURL, NULL)) {
1003 *error = errors::kLaunchPathAndURLAreExclusive; 970 *error = errors::kLaunchPathAndURLAreExclusive;
1004 return false; 971 return false;
1005 } 972 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1083 GURL::Replacements replacements; 1050 GURL::Replacements replacements;
1084 replacements.SetPathStr(path); 1051 replacements.SetPathStr(path);
1085 GURL cloud_print_enable_connector_url = 1052 GURL cloud_print_enable_connector_url =
1086 cloud_print_service_url.ReplaceComponents(replacements); 1053 cloud_print_service_url.ReplaceComponents(replacements);
1087 OverrideLaunchUrl(cloud_print_enable_connector_url); 1054 OverrideLaunchUrl(cloud_print_enable_connector_url);
1088 } 1055 }
1089 } 1056 }
1090 return true; 1057 return true;
1091 } 1058 }
1092 1059
1093 bool Extension::LoadLaunchContainer(const DictionaryValue* manifest, 1060 bool Extension::LoadLaunchContainer(const ManifestValue* manifest,
1094 std::string* error) { 1061 std::string* error) {
1095 Value* temp = NULL; 1062 Value* temp = NULL;
1096 if (!manifest->Get(keys::kLaunchContainer, &temp)) 1063 if (!manifest->Get(keys::kLaunchContainer, &temp))
1097 return true; 1064 return true;
1098 1065
1099 std::string launch_container_string; 1066 std::string launch_container_string;
1100 if (!temp->GetAsString(&launch_container_string)) { 1067 if (!temp->GetAsString(&launch_container_string)) {
1101 *error = errors::kInvalidLaunchContainer; 1068 *error = errors::kInvalidLaunchContainer;
1102 return false; 1069 return false;
1103 } 1070 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1136 if (!temp->GetAsInteger(&launch_height_) || launch_height_ < 0) { 1103 if (!temp->GetAsInteger(&launch_height_) || launch_height_ < 0) {
1137 launch_height_ = 0; 1104 launch_height_ = 0;
1138 *error = errors::kInvalidLaunchHeight; 1105 *error = errors::kInvalidLaunchHeight;
1139 return false; 1106 return false;
1140 } 1107 }
1141 } 1108 }
1142 1109
1143 return true; 1110 return true;
1144 } 1111 }
1145 1112
1146 bool Extension::LoadAppIsolation(const DictionaryValue* manifest, 1113 bool Extension::LoadAppIsolation(const ManifestValue* manifest,
1147 std::string* error) { 1114 std::string* error) {
1148 Value* temp = NULL; 1115 Value* temp = NULL;
1149 if (!manifest->Get(keys::kIsolation, &temp)) 1116 if (!manifest->Get(keys::kIsolation, &temp))
1150 return true; 1117 return true;
1151 1118
1152 if (temp->GetType() != Value::TYPE_LIST) { 1119 if (temp->GetType() != Value::TYPE_LIST) {
1153 *error = errors::kInvalidIsolation; 1120 *error = errors::kInvalidIsolation;
1154 return false; 1121 return false;
1155 } 1122 }
1156 1123
(...skipping 11 matching lines...) Expand all
1168 if (isolation_string == values::kIsolatedStorage) { 1135 if (isolation_string == values::kIsolatedStorage) {
1169 is_storage_isolated_ = true; 1136 is_storage_isolated_ = true;
1170 } else { 1137 } else {
1171 DLOG(WARNING) << "Did not recognize isolation type: " 1138 DLOG(WARNING) << "Did not recognize isolation type: "
1172 << isolation_string; 1139 << isolation_string;
1173 } 1140 }
1174 } 1141 }
1175 return true; 1142 return true;
1176 } 1143 }
1177 1144
1178 bool Extension::LoadWebIntentServices(const base::DictionaryValue& manifest, 1145 bool Extension::LoadWebIntentServices(const ManifestValue& manifest,
1179 std::string* error) { 1146 std::string* error) {
1180 DCHECK(error); 1147 DCHECK(error);
1181 1148
1182 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableWebIntents)) 1149 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableWebIntents))
1183 return true; 1150 return true;
1184 1151
1185 if (!manifest.HasKey(keys::kIntents)) 1152 if (!manifest.HasKey(keys::kIntents))
1186 return true; 1153 return true;
1187 1154
1188 DictionaryValue* all_services = NULL; 1155 DictionaryValue* all_services = NULL;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1238 service.disposition = 1205 service.disposition =
1239 webkit_glue::WebIntentServiceData::DISPOSITION_WINDOW; 1206 webkit_glue::WebIntentServiceData::DISPOSITION_WINDOW;
1240 } 1207 }
1241 } 1208 }
1242 1209
1243 intents_services_.push_back(service); 1210 intents_services_.push_back(service);
1244 } 1211 }
1245 return true; 1212 return true;
1246 } 1213 }
1247 1214
1248
1249 bool Extension::EnsureNotHybridApp(const DictionaryValue* manifest,
1250 std::string* error) {
1251 if (web_extent().is_empty())
1252 return true;
1253
1254 for (DictionaryValue::key_iterator key = manifest->begin_keys();
1255 key != manifest->end_keys(); ++key) {
1256 if (!IsBaseCrxKey(*key) &&
1257 *key != keys::kApp &&
1258 *key != keys::kPermissions &&
1259 *key != keys::kOptionalPermissions &&
1260 *key != keys::kOptionsPage &&
1261 *key != keys::kBackground &&
1262 *key != keys::kOfflineEnabled &&
1263 *key != keys::kMinimumChromeVersion &&
1264 *key != keys::kRequirements) {
1265 *error = ExtensionErrorUtils::FormatErrorMessage(
1266 errors::kHostedAppsCannotIncludeExtensionFeatures, *key);
1267 return false;
1268 }
1269 }
1270
1271 return true;
1272 }
1273
1274 // static 1215 // static
1275 bool Extension::IsTrustedId(const std::string& id) { 1216 bool Extension::IsTrustedId(const std::string& id) {
1276 // See http://b/4946060 for more details. 1217 // See http://b/4946060 for more details.
1277 return id == std::string("nckgahadagoaajjgafhacjanaoiihapd"); 1218 return id == std::string("nckgahadagoaajjgafhacjanaoiihapd");
1278 } 1219 }
1279 1220
1280 Extension::Extension(const FilePath& path, Location location) 1221 Extension::Extension(const FilePath& path, Location location)
1281 : manifest_version_(0), 1222 : manifest_version_(0),
1282 incognito_split_mode_(false), 1223 incognito_split_mode_(false),
1283 offline_enabled_(false), 1224 offline_enabled_(false),
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1437 return *ResourceBundle::GetSharedInstance().GetBitmapNamed( 1378 return *ResourceBundle::GetSharedInstance().GetBitmapNamed(
1438 IDR_EXTENSION_DEFAULT_ICON); 1379 IDR_EXTENSION_DEFAULT_ICON);
1439 } 1380 }
1440 } 1381 }
1441 1382
1442 GURL Extension::GetBaseURLFromExtensionId(const std::string& extension_id) { 1383 GURL Extension::GetBaseURLFromExtensionId(const std::string& extension_id) {
1443 return GURL(std::string(chrome::kExtensionScheme) + 1384 return GURL(std::string(chrome::kExtensionScheme) +
1444 chrome::kStandardSchemeSeparator + extension_id + "/"); 1385 chrome::kStandardSchemeSeparator + extension_id + "/");
1445 } 1386 }
1446 1387
1447 bool Extension::InitFromValue(const DictionaryValue& source, int flags, 1388 bool Extension::InitFromValue(const ManifestValue& manifest, int flags,
1448 std::string* error) { 1389 std::string* error) {
1449 DCHECK(error); 1390 DCHECK(error);
1450 base::AutoLock auto_lock(runtime_data_lock_); 1391 base::AutoLock auto_lock(runtime_data_lock_);
1392
1393 if (!manifest.ValidateManifest(error))
1394 return false;
1395
1451 // When strict error checks are enabled, make URL pattern parsing strict. 1396 // When strict error checks are enabled, make URL pattern parsing strict.
1452 URLPattern::ParseOption parse_strictness = 1397 URLPattern::ParseOption parse_strictness =
1453 (flags & STRICT_ERROR_CHECKS ? URLPattern::ERROR_ON_PORTS 1398 (flags & STRICT_ERROR_CHECKS ? URLPattern::ERROR_ON_PORTS
1454 : URLPattern::IGNORE_PORTS); 1399 : URLPattern::IGNORE_PORTS);
1455 1400
1456 // Initialize permissions with an empty, default permission set. 1401 // Initialize permissions with an empty, default permission set.
1457 runtime_data_.SetActivePermissions(new ExtensionPermissionSet()); 1402 runtime_data_.SetActivePermissions(new ExtensionPermissionSet());
1458 optional_permission_set_ = new ExtensionPermissionSet(); 1403 optional_permission_set_ = new ExtensionPermissionSet();
1459 required_permission_set_ = new ExtensionPermissionSet(); 1404 required_permission_set_ = new ExtensionPermissionSet();
1460 1405
1461 if (source.HasKey(keys::kManifestVersion)) { 1406 if (manifest.HasKey(keys::kManifestVersion)) {
1462 int manifest_version = 0; 1407 int manifest_version = 0;
1463 if (!source.GetInteger(keys::kManifestVersion, &manifest_version) || 1408 if (!manifest.GetInteger(keys::kManifestVersion, &manifest_version) ||
1464 manifest_version < 1) { 1409 manifest_version < 1) {
1465 *error = errors::kInvalidManifestVersion; 1410 *error = errors::kInvalidManifestVersion;
1466 return false; 1411 return false;
1467 } 1412 }
1468 manifest_version_ = manifest_version; 1413 manifest_version_ = manifest_version;
1469 } else { 1414 } else {
1470 // Version 1 was the original version, which lacked a version indicator. 1415 // Version 1 was the original version, which lacked a version indicator.
1471 manifest_version_ = 1; 1416 manifest_version_ = 1;
1472 } 1417 }
1473 1418
1474 if (source.HasKey(keys::kPublicKey)) { 1419 if (manifest.HasKey(keys::kPublicKey)) {
1475 std::string public_key_bytes; 1420 std::string public_key_bytes;
1476 if (!source.GetString(keys::kPublicKey, 1421 if (!manifest.GetString(keys::kPublicKey,
1477 &public_key_) || 1422 &public_key_) ||
1478 !ParsePEMKeyBytes(public_key_, 1423 !ParsePEMKeyBytes(public_key_,
1479 &public_key_bytes) || 1424 &public_key_bytes) ||
1480 !GenerateId(public_key_bytes, &id_)) { 1425 !GenerateId(public_key_bytes, &id_)) {
1481 *error = errors::kInvalidKey; 1426 *error = errors::kInvalidKey;
1482 return false; 1427 return false;
1483 } 1428 }
1484 } else if (flags & REQUIRE_KEY) { 1429 } else if (flags & REQUIRE_KEY) {
1485 *error = errors::kInvalidKey; 1430 *error = errors::kInvalidKey;
1486 return false; 1431 return false;
1487 } else { 1432 } else {
1488 // If there is a path, we generate the ID from it. This is useful for 1433 // If there is a path, we generate the ID from it. This is useful for
1489 // development mode, because it keeps the ID stable across restarts and 1434 // development mode, because it keeps the ID stable across restarts and
1490 // reloading the extension. 1435 // reloading the extension.
1491 id_ = Extension::GenerateIdForPath(path()); 1436 id_ = Extension::GenerateIdForPath(path());
1492 if (id_.empty()) { 1437 if (id_.empty()) {
1493 NOTREACHED() << "Could not create ID from path."; 1438 NOTREACHED() << "Could not create ID from path.";
1494 return false; 1439 return false;
1495 } 1440 }
1496 } 1441 }
1497 1442
1498 creation_flags_ = flags; 1443 creation_flags_ = flags;
1499 1444
1500 // Make a copy of the manifest so we can store it in prefs. 1445 // Make a copy of the manifest so we can store it in prefs.
1501 manifest_value_.reset(source.DeepCopy()); 1446 manifest_value_.reset(manifest.DeepCopy());
1502 1447
1503 // Initialize the URL. 1448 // Initialize the URL.
1504 extension_url_ = Extension::GetBaseURLFromExtensionId(id()); 1449 extension_url_ = Extension::GetBaseURLFromExtensionId(id());
1505 1450
1506 // Initialize version. 1451 // Initialize version.
1507 std::string version_str; 1452 std::string version_str;
1508 if (!source.GetString(keys::kVersion, &version_str)) { 1453 if (!manifest.GetString(keys::kVersion, &version_str)) {
1509 *error = errors::kInvalidVersion; 1454 *error = errors::kInvalidVersion;
1510 return false; 1455 return false;
1511 } 1456 }
1512 version_.reset(Version::GetVersionFromString(version_str)); 1457 version_.reset(Version::GetVersionFromString(version_str));
1513 if (!version_.get() || 1458 if (!version_.get() ||
1514 version_->components().size() > 4) { 1459 version_->components().size() > 4) {
1515 *error = errors::kInvalidVersion; 1460 *error = errors::kInvalidVersion;
1516 return false; 1461 return false;
1517 } 1462 }
1518 1463
1519 // Initialize name. 1464 // Initialize name.
1520 string16 localized_name; 1465 string16 localized_name;
1521 if (!source.GetString(keys::kName, &localized_name)) { 1466 if (!manifest.GetString(keys::kName, &localized_name)) {
1522 *error = errors::kInvalidName; 1467 *error = errors::kInvalidName;
1523 return false; 1468 return false;
1524 } 1469 }
1525 base::i18n::AdjustStringForLocaleDirection(&localized_name); 1470 base::i18n::AdjustStringForLocaleDirection(&localized_name);
1526 name_ = UTF16ToUTF8(localized_name); 1471 name_ = UTF16ToUTF8(localized_name);
1527 1472
1528 // Load App settings. LoadExtent at least has to be done before 1473 // Load App settings. LoadExtent at least has to be done before
1529 // ParsePermissions(), because the valid permissions depend on what type of 1474 // ParsePermissions(), because the valid permissions depend on what type of
1530 // package this is. 1475 // package this is.
1531 if (!LoadIsApp(manifest_value_.get(), error) || 1476 if (!LoadIsApp(manifest_value_.get(), error))
1532 !LoadExtent(manifest_value_.get(), keys::kWebURLs, 1477 return false;
1533 &extent_, 1478
1534 errors::kInvalidWebURLs, errors::kInvalidWebURL, 1479 if (is_app() &&
1535 parse_strictness, error) || 1480 (!LoadExtent(manifest_value_.get(), keys::kWebURLs,
1536 !EnsureNotHybridApp(manifest_value_.get(), error) || 1481 &extent_,
1537 !LoadLaunchURL(manifest_value_.get(), error) || 1482 errors::kInvalidWebURLs, errors::kInvalidWebURL,
1538 !LoadLaunchContainer(manifest_value_.get(), error)) { 1483 parse_strictness, error) ||
1484 !LoadLaunchURL(manifest_value_.get(), error) ||
1485 !LoadLaunchContainer(manifest_value_.get(), error))) {
1539 return false; 1486 return false;
1540 } 1487 }
1541 1488
1542 if (is_platform_app_) { 1489 if (is_platform_app_) {
1543 if (launch_container() != extension_misc::LAUNCH_PANEL) { 1490 if (launch_container() != extension_misc::LAUNCH_PANEL) {
1544 *error = errors::kInvalidLaunchContainerForPlatform; 1491 *error = errors::kInvalidLaunchContainerForPlatform;
1545 return false; 1492 return false;
1546 } 1493 }
1547 } 1494 }
1548 1495
1549 // Initialize the permissions (optional). 1496 // Initialize the permissions (optional).
1550 ExtensionAPIPermissionSet api_permissions; 1497 ExtensionAPIPermissionSet api_permissions;
1551 URLPatternSet host_permissions; 1498 URLPatternSet host_permissions;
1552 if (!ParsePermissions(&source, 1499 if (!ParsePermissions(manifest_value_.get(),
1553 keys::kPermissions, 1500 keys::kPermissions,
1554 flags, 1501 flags,
1555 error, 1502 error,
1556 &api_permissions, 1503 &api_permissions,
1557 &host_permissions)) { 1504 &host_permissions)) {
1558 return false; 1505 return false;
1559 } 1506 }
1560 1507
1561 // Initialize the optional permissions (optional). 1508 // Initialize the optional permissions (optional).
1562 ExtensionAPIPermissionSet optional_api_permissions; 1509 ExtensionAPIPermissionSet optional_api_permissions;
1563 URLPatternSet optional_host_permissions; 1510 URLPatternSet optional_host_permissions;
1564 if (!ParsePermissions(&source, 1511 if (!ParsePermissions(manifest_value_.get(),
1565 keys::kOptionalPermissions, 1512 keys::kOptionalPermissions,
1566 flags, 1513 flags,
1567 error, 1514 error,
1568 &optional_api_permissions, 1515 &optional_api_permissions,
1569 &optional_host_permissions)) { 1516 &optional_host_permissions)) {
1570 return false; 1517 return false;
1571 } 1518 }
1572 1519
1573 // Initialize description (if present). 1520 // Initialize description (if present).
1574 if (source.HasKey(keys::kDescription)) { 1521 if (manifest.HasKey(keys::kDescription)) {
1575 if (!source.GetString(keys::kDescription, 1522 if (!manifest.GetString(keys::kDescription,
1576 &description_)) { 1523 &description_)) {
1577 *error = errors::kInvalidDescription; 1524 *error = errors::kInvalidDescription;
1578 return false; 1525 return false;
1579 } 1526 }
1580 } 1527 }
1581 1528
1582 // Initialize homepage url (if present). 1529 // Initialize homepage url (if present).
1583 if (source.HasKey(keys::kHomepageURL)) { 1530 if (manifest.HasKey(keys::kHomepageURL)) {
1584 std::string tmp; 1531 std::string tmp;
1585 if (!source.GetString(keys::kHomepageURL, &tmp)) { 1532 if (!manifest.GetString(keys::kHomepageURL, &tmp)) {
1586 *error = ExtensionErrorUtils::FormatErrorMessage( 1533 *error = ExtensionErrorUtils::FormatErrorMessage(
1587 errors::kInvalidHomepageURL, ""); 1534 errors::kInvalidHomepageURL, "");
1588 return false; 1535 return false;
1589 } 1536 }
1590 homepage_url_ = GURL(tmp); 1537 homepage_url_ = GURL(tmp);
1591 if (!homepage_url_.is_valid() || 1538 if (!homepage_url_.is_valid() ||
1592 (!homepage_url_.SchemeIs("http") && 1539 (!homepage_url_.SchemeIs("http") &&
1593 !homepage_url_.SchemeIs("https"))) { 1540 !homepage_url_.SchemeIs("https"))) {
1594 *error = ExtensionErrorUtils::FormatErrorMessage( 1541 *error = ExtensionErrorUtils::FormatErrorMessage(
1595 errors::kInvalidHomepageURL, tmp); 1542 errors::kInvalidHomepageURL, tmp);
1596 return false; 1543 return false;
1597 } 1544 }
1598 } 1545 }
1599 1546
1600 // Initialize update url (if present). 1547 // Initialize update url (if present).
1601 if (source.HasKey(keys::kUpdateURL)) { 1548 if (manifest.HasKey(keys::kUpdateURL)) {
1602 std::string tmp; 1549 std::string tmp;
1603 if (!source.GetString(keys::kUpdateURL, &tmp)) { 1550 if (!manifest.GetString(keys::kUpdateURL, &tmp)) {
1604 *error = ExtensionErrorUtils::FormatErrorMessage( 1551 *error = ExtensionErrorUtils::FormatErrorMessage(
1605 errors::kInvalidUpdateURL, ""); 1552 errors::kInvalidUpdateURL, "");
1606 return false; 1553 return false;
1607 } 1554 }
1608 update_url_ = GURL(tmp); 1555 update_url_ = GURL(tmp);
1609 if (!update_url_.is_valid() || 1556 if (!update_url_.is_valid() ||
1610 update_url_.has_ref()) { 1557 update_url_.has_ref()) {
1611 *error = ExtensionErrorUtils::FormatErrorMessage( 1558 *error = ExtensionErrorUtils::FormatErrorMessage(
1612 errors::kInvalidUpdateURL, tmp); 1559 errors::kInvalidUpdateURL, tmp);
1613 return false; 1560 return false;
1614 } 1561 }
1615 } 1562 }
1616 1563
1617 // Validate minimum Chrome version (if present). We don't need to store this, 1564 // Validate minimum Chrome version (if present). We don't need to store this,
1618 // since the extension is not valid if it is incorrect. 1565 // since the extension is not valid if it is incorrect.
1619 if (source.HasKey(keys::kMinimumChromeVersion)) { 1566 if (manifest.HasKey(keys::kMinimumChromeVersion)) {
1620 std::string minimum_version_string; 1567 std::string minimum_version_string;
1621 if (!source.GetString(keys::kMinimumChromeVersion, 1568 if (!manifest.GetString(keys::kMinimumChromeVersion,
1622 &minimum_version_string)) { 1569 &minimum_version_string)) {
1623 *error = errors::kInvalidMinimumChromeVersion; 1570 *error = errors::kInvalidMinimumChromeVersion;
1624 return false; 1571 return false;
1625 } 1572 }
1626 1573
1627 scoped_ptr<Version> minimum_version( 1574 scoped_ptr<Version> minimum_version(
1628 Version::GetVersionFromString(minimum_version_string)); 1575 Version::GetVersionFromString(minimum_version_string));
1629 if (!minimum_version.get()) { 1576 if (!minimum_version.get()) {
1630 *error = errors::kInvalidMinimumChromeVersion; 1577 *error = errors::kInvalidMinimumChromeVersion;
1631 return false; 1578 return false;
(...skipping 15 matching lines...) Expand all
1647 if (current_version->CompareTo(*minimum_version) < 0) { 1594 if (current_version->CompareTo(*minimum_version) < 0) {
1648 *error = ExtensionErrorUtils::FormatErrorMessage( 1595 *error = ExtensionErrorUtils::FormatErrorMessage(
1649 errors::kChromeVersionTooLow, 1596 errors::kChromeVersionTooLow,
1650 l10n_util::GetStringUTF8(IDS_PRODUCT_NAME), 1597 l10n_util::GetStringUTF8(IDS_PRODUCT_NAME),
1651 minimum_version_string); 1598 minimum_version_string);
1652 return false; 1599 return false;
1653 } 1600 }
1654 } 1601 }
1655 1602
1656 // Initialize converted_from_user_script (if present) 1603 // Initialize converted_from_user_script (if present)
1657 source.GetBoolean(keys::kConvertedFromUserScript, 1604 if (manifest.HasKey(keys::kConvertedFromUserScript))
1658 &converted_from_user_script_); 1605 manifest.GetBoolean(keys::kConvertedFromUserScript,
1606 &converted_from_user_script_);
1659 1607
1660 // Initialize icons (if present). 1608 // Initialize icons (if present).
1661 if (source.HasKey(keys::kIcons)) { 1609 if (manifest.HasKey(keys::kIcons)) {
1662 DictionaryValue* icons_value = NULL; 1610 DictionaryValue* icons_value = NULL;
1663 if (!source.GetDictionary(keys::kIcons, &icons_value)) { 1611 if (!manifest.GetDictionary(keys::kIcons, &icons_value)) {
1664 *error = errors::kInvalidIcons; 1612 *error = errors::kInvalidIcons;
1665 return false; 1613 return false;
1666 } 1614 }
1667 1615
1668 for (size_t i = 0; i < arraysize(kIconSizes); ++i) { 1616 for (size_t i = 0; i < arraysize(kIconSizes); ++i) {
1669 std::string key = base::IntToString(kIconSizes[i]); 1617 std::string key = base::IntToString(kIconSizes[i]);
1670 if (icons_value->HasKey(key)) { 1618 if (icons_value->HasKey(key)) {
1671 std::string icon_path; 1619 std::string icon_path;
1672 if (!icons_value->GetString(key, &icon_path)) { 1620 if (!icons_value->GetString(key, &icon_path)) {
1673 *error = ExtensionErrorUtils::FormatErrorMessage( 1621 *error = ExtensionErrorUtils::FormatErrorMessage(
(...skipping 10 matching lines...) Expand all
1684 return false; 1632 return false;
1685 } 1633 }
1686 1634
1687 icons_.Add(kIconSizes[i], icon_path); 1635 icons_.Add(kIconSizes[i], icon_path);
1688 } 1636 }
1689 } 1637 }
1690 } 1638 }
1691 1639
1692 // Initialize themes (if present). 1640 // Initialize themes (if present).
1693 is_theme_ = false; 1641 is_theme_ = false;
1694 if (source.HasKey(keys::kTheme)) { 1642 if (manifest.HasKey(keys::kTheme)) {
1695 // Themes cannot contain extension keys.
1696 if (ContainsNonThemeKeys(source)) {
1697 *error = errors::kThemesCannotContainExtensions;
1698 return false;
1699 }
1700
1701 DictionaryValue* theme_value = NULL; 1643 DictionaryValue* theme_value = NULL;
1702 if (!source.GetDictionary(keys::kTheme, &theme_value)) { 1644 if (!manifest.GetDictionary(keys::kTheme, &theme_value)) {
1703 *error = errors::kInvalidTheme; 1645 *error = errors::kInvalidTheme;
1704 return false; 1646 return false;
1705 } 1647 }
1706 is_theme_ = true; 1648 is_theme_ = true;
1707 1649
1708 DictionaryValue* images_value = NULL; 1650 DictionaryValue* images_value = NULL;
1709 if (theme_value->GetDictionary(keys::kThemeImages, &images_value)) { 1651 if (theme_value->GetDictionary(keys::kThemeImages, &images_value)) {
1710 // Validate that the images are all strings 1652 // Validate that the images are all strings
1711 for (DictionaryValue::key_iterator iter = images_value->begin_keys(); 1653 for (DictionaryValue::key_iterator iter = images_value->begin_keys();
1712 iter != images_value->end_keys(); ++iter) { 1654 iter != images_value->end_keys(); ++iter) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1769 if (theme_value->GetDictionary(keys::kThemeDisplayProperties, 1711 if (theme_value->GetDictionary(keys::kThemeDisplayProperties,
1770 &display_properties_value)) { 1712 &display_properties_value)) {
1771 theme_display_properties_.reset( 1713 theme_display_properties_.reset(
1772 display_properties_value->DeepCopy()); 1714 display_properties_value->DeepCopy());
1773 } 1715 }
1774 1716
1775 return true; 1717 return true;
1776 } 1718 }
1777 1719
1778 // Initialize plugins (optional). 1720 // Initialize plugins (optional).
1779 if (source.HasKey(keys::kPlugins)) { 1721 if (manifest.HasKey(keys::kPlugins)) {
1780 ListValue* list_value = NULL; 1722 ListValue* list_value = NULL;
1781 if (!source.GetList(keys::kPlugins, &list_value)) { 1723 if (!manifest.GetList(keys::kPlugins, &list_value)) {
1782 *error = errors::kInvalidPlugins; 1724 *error = errors::kInvalidPlugins;
1783 return false; 1725 return false;
1784 } 1726 }
1785 1727
1786 for (size_t i = 0; i < list_value->GetSize(); ++i) { 1728 for (size_t i = 0; i < list_value->GetSize(); ++i) {
1787 DictionaryValue* plugin_value = NULL; 1729 DictionaryValue* plugin_value = NULL;
1788 std::string path_str; 1730 std::string path_str;
1789 bool is_public = false; 1731 bool is_public = false;
1790 1732
1791 if (!list_value->GetDictionary(i, &plugin_value)) { 1733 if (!list_value->GetDictionary(i, &plugin_value)) {
(...skipping 21 matching lines...) Expand all
1813 // parse the manifest entry so that error messages are consistently 1755 // parse the manifest entry so that error messages are consistently
1814 // displayed across platforms. 1756 // displayed across platforms.
1815 #if !defined(OS_CHROMEOS) 1757 #if !defined(OS_CHROMEOS)
1816 plugins_.push_back(PluginInfo()); 1758 plugins_.push_back(PluginInfo());
1817 plugins_.back().path = path().Append(FilePath::FromUTF8Unsafe(path_str)); 1759 plugins_.back().path = path().Append(FilePath::FromUTF8Unsafe(path_str));
1818 plugins_.back().is_public = is_public; 1760 plugins_.back().is_public = is_public;
1819 #endif 1761 #endif
1820 } 1762 }
1821 } 1763 }
1822 1764
1823 if (source.HasKey(keys::kNaClModules)) { 1765 if (manifest.HasKey(keys::kNaClModules)) {
1824 ListValue* list_value = NULL; 1766 ListValue* list_value = NULL;
1825 if (!source.GetList(keys::kNaClModules, &list_value)) { 1767 if (!manifest.GetList(keys::kNaClModules, &list_value)) {
1826 *error = errors::kInvalidNaClModules; 1768 *error = errors::kInvalidNaClModules;
1827 return false; 1769 return false;
1828 } 1770 }
1829 1771
1830 for (size_t i = 0; i < list_value->GetSize(); ++i) { 1772 for (size_t i = 0; i < list_value->GetSize(); ++i) {
1831 DictionaryValue* module_value = NULL; 1773 DictionaryValue* module_value = NULL;
1832 std::string path_str; 1774 std::string path_str;
1833 std::string mime_type; 1775 std::string mime_type;
1834 1776
1835 if (!list_value->GetDictionary(i, &module_value)) { 1777 if (!list_value->GetDictionary(i, &module_value)) {
(...skipping 15 matching lines...) Expand all
1851 return false; 1793 return false;
1852 } 1794 }
1853 1795
1854 nacl_modules_.push_back(NaClModuleInfo()); 1796 nacl_modules_.push_back(NaClModuleInfo());
1855 nacl_modules_.back().url = GetResourceURL(path_str); 1797 nacl_modules_.back().url = GetResourceURL(path_str);
1856 nacl_modules_.back().mime_type = mime_type; 1798 nacl_modules_.back().mime_type = mime_type;
1857 } 1799 }
1858 } 1800 }
1859 1801
1860 // Initialize content scripts (optional). 1802 // Initialize content scripts (optional).
1861 if (source.HasKey(keys::kContentScripts)) { 1803 if (manifest.HasKey(keys::kContentScripts)) {
1862 ListValue* list_value; 1804 ListValue* list_value;
1863 if (!source.GetList(keys::kContentScripts, &list_value)) { 1805 if (!manifest.GetList(keys::kContentScripts, &list_value)) {
1864 *error = errors::kInvalidContentScriptsList; 1806 *error = errors::kInvalidContentScriptsList;
1865 return false; 1807 return false;
1866 } 1808 }
1867 1809
1868 for (size_t i = 0; i < list_value->GetSize(); ++i) { 1810 for (size_t i = 0; i < list_value->GetSize(); ++i) {
1869 DictionaryValue* content_script = NULL; 1811 DictionaryValue* content_script = NULL;
1870 if (!list_value->GetDictionary(i, &content_script)) { 1812 if (!list_value->GetDictionary(i, &content_script)) {
1871 *error = ExtensionErrorUtils::FormatErrorMessage( 1813 *error = ExtensionErrorUtils::FormatErrorMessage(
1872 errors::kInvalidContentScript, base::IntToString(i)); 1814 errors::kInvalidContentScript, base::IntToString(i));
1873 return false; 1815 return false;
1874 } 1816 }
1875 1817
1876 UserScript script; 1818 UserScript script;
1877 if (!LoadUserScriptHelper(content_script, i, flags, error, &script)) 1819 if (!LoadUserScriptHelper(content_script, i, flags, error, &script))
1878 return false; // Failed to parse script context definition. 1820 return false; // Failed to parse script context definition.
1879 script.set_extension_id(id()); 1821 script.set_extension_id(id());
1880 if (converted_from_user_script_) { 1822 if (converted_from_user_script_) {
1881 script.set_emulate_greasemonkey(true); 1823 script.set_emulate_greasemonkey(true);
1882 script.set_match_all_frames(true); // Greasemonkey matches all frames. 1824 script.set_match_all_frames(true); // Greasemonkey matches all frames.
1883 } 1825 }
1884 content_scripts_.push_back(script); 1826 content_scripts_.push_back(script);
1885 } 1827 }
1886 } 1828 }
1887 1829
1888 // Initialize page action (optional). 1830 // Initialize page action (optional).
1889 DictionaryValue* page_action_value = NULL; 1831 DictionaryValue* page_action_value = NULL;
1890 1832
1891 if (source.HasKey(keys::kPageActions)) { 1833 if (manifest.HasKey(keys::kPageActions)) {
1892 ListValue* list_value = NULL; 1834 ListValue* list_value = NULL;
1893 if (!source.GetList(keys::kPageActions, &list_value)) { 1835 if (!manifest.GetList(keys::kPageActions, &list_value)) {
1894 *error = errors::kInvalidPageActionsList; 1836 *error = errors::kInvalidPageActionsList;
1895 return false; 1837 return false;
1896 } 1838 }
1897 1839
1898 size_t list_value_length = list_value->GetSize(); 1840 size_t list_value_length = list_value->GetSize();
1899 1841
1900 if (list_value_length == 0u) { 1842 if (list_value_length == 0u) {
1901 // A list with zero items is allowed, and is equivalent to not having 1843 // A list with zero items is allowed, and is equivalent to not having
1902 // a page_actions key in the manifest. Don't set |page_action_value|. 1844 // a page_actions key in the manifest. Don't set |page_action_value|.
1903 } else if (list_value_length == 1u) { 1845 } else if (list_value_length == 1u) {
1904 if (!list_value->GetDictionary(0, &page_action_value)) { 1846 if (!list_value->GetDictionary(0, &page_action_value)) {
1905 *error = errors::kInvalidPageAction; 1847 *error = errors::kInvalidPageAction;
1906 return false; 1848 return false;
1907 } 1849 }
1908 } else { // list_value_length > 1u. 1850 } else { // list_value_length > 1u.
1909 *error = errors::kInvalidPageActionsListSize; 1851 *error = errors::kInvalidPageActionsListSize;
1910 return false; 1852 return false;
1911 } 1853 }
1912 } else if (source.HasKey(keys::kPageAction)) { 1854 } else if (manifest.HasKey(keys::kPageAction)) {
1913 if (!source.GetDictionary(keys::kPageAction, &page_action_value)) { 1855 if (!manifest.GetDictionary(keys::kPageAction, &page_action_value)) {
1914 *error = errors::kInvalidPageAction; 1856 *error = errors::kInvalidPageAction;
1915 return false; 1857 return false;
1916 } 1858 }
1917 } 1859 }
1918 1860
1919 // If page_action_value is not NULL, then there was a valid page action. 1861 // If page_action_value is not NULL, then there was a valid page action.
1920 if (page_action_value) { 1862 if (page_action_value) {
1921 page_action_.reset( 1863 page_action_.reset(
1922 LoadExtensionActionHelper(page_action_value, error)); 1864 LoadExtensionActionHelper(page_action_value, error));
1923 if (!page_action_.get()) 1865 if (!page_action_.get())
1924 return false; // Failed to parse page action definition. 1866 return false; // Failed to parse page action definition.
1925 } 1867 }
1926 1868
1927 // Initialize browser action (optional). 1869 // Initialize browser action (optional).
1928 if (source.HasKey(keys::kBrowserAction)) { 1870 if (manifest.HasKey(keys::kBrowserAction)) {
1929 DictionaryValue* browser_action_value = NULL; 1871 DictionaryValue* browser_action_value = NULL;
1930 if (!source.GetDictionary(keys::kBrowserAction, &browser_action_value)) { 1872 if (!manifest.GetDictionary(keys::kBrowserAction, &browser_action_value)) {
1931 *error = errors::kInvalidBrowserAction; 1873 *error = errors::kInvalidBrowserAction;
1932 return false; 1874 return false;
1933 } 1875 }
1934 1876
1935 browser_action_.reset( 1877 browser_action_.reset(
1936 LoadExtensionActionHelper(browser_action_value, error)); 1878 LoadExtensionActionHelper(browser_action_value, error));
1937 if (!browser_action_.get()) 1879 if (!browser_action_.get())
1938 return false; // Failed to parse browser action definition. 1880 return false; // Failed to parse browser action definition.
1939 } 1881 }
1940 1882
1941 // Initialize file browser actions (optional). 1883 // Initialize file browser actions (optional).
1942 if (source.HasKey(keys::kFileBrowserHandlers)) { 1884 if (manifest.HasKey(keys::kFileBrowserHandlers)) {
1943 ListValue* file_browser_handlers_value = NULL; 1885 ListValue* file_browser_handlers_value = NULL;
1944 if (!source.GetList(keys::kFileBrowserHandlers, 1886 if (!manifest.GetList(keys::kFileBrowserHandlers,
1945 &file_browser_handlers_value)) { 1887 &file_browser_handlers_value)) {
1946 *error = errors::kInvalidFileBrowserHandler; 1888 *error = errors::kInvalidFileBrowserHandler;
1947 return false; 1889 return false;
1948 } 1890 }
1949 1891
1950 file_browser_handlers_.reset( 1892 file_browser_handlers_.reset(
1951 LoadFileBrowserHandlers(file_browser_handlers_value, error)); 1893 LoadFileBrowserHandlers(file_browser_handlers_value, error));
1952 if (!file_browser_handlers_.get()) 1894 if (!file_browser_handlers_.get())
1953 return false; // Failed to parse file browser actions definition. 1895 return false; // Failed to parse file browser actions definition.
1954 } 1896 }
1955 1897
1956 // App isolation. 1898 // App isolation.
1957 if (api_permissions.count(ExtensionAPIPermission::kExperimental)) { 1899 if (api_permissions.count(ExtensionAPIPermission::kExperimental)) {
1958 if (!LoadAppIsolation(manifest_value_.get(), error)) 1900 if (is_app() && !LoadAppIsolation(manifest_value_.get(), error))
1959 return false; 1901 return false;
1960 } 1902 }
1961 1903
1962 // Initialize options page url (optional). 1904 // Initialize options page url (optional).
1963 // Function LoadIsApp() set is_app_ above. 1905 // Function LoadIsApp() set is_app_ above.
1964 if (source.HasKey(keys::kOptionsPage)) { 1906 if (manifest.HasKey(keys::kOptionsPage)) {
1965 std::string options_str; 1907 std::string options_str;
1966 if (!source.GetString(keys::kOptionsPage, &options_str)) { 1908 if (!manifest.GetString(keys::kOptionsPage, &options_str)) {
1967 *error = errors::kInvalidOptionsPage; 1909 *error = errors::kInvalidOptionsPage;
1968 return false; 1910 return false;
1969 } 1911 }
1970 1912
1971 if (is_hosted_app()) { 1913 if (is_hosted_app()) {
1972 // hosted apps require an absolute URL. 1914 // hosted apps require an absolute URL.
1973 GURL options_url(options_str); 1915 GURL options_url(options_str);
1974 if (!options_url.is_valid() || 1916 if (!options_url.is_valid() ||
1975 !(options_url.SchemeIs("http") || options_url.SchemeIs("https"))) { 1917 !(options_url.SchemeIs("http") || options_url.SchemeIs("https"))) {
1976 *error = errors::kInvalidOptionsPageInHostedApp; 1918 *error = errors::kInvalidOptionsPageInHostedApp;
1977 return false; 1919 return false;
1978 } 1920 }
1979 options_url_ = options_url; 1921 options_url_ = options_url;
1980 } else { 1922 } else {
1981 GURL absolute(options_str); 1923 GURL absolute(options_str);
1982 if (absolute.is_valid()) { 1924 if (absolute.is_valid()) {
1983 *error = errors::kInvalidOptionsPageExpectUrlInPackage; 1925 *error = errors::kInvalidOptionsPageExpectUrlInPackage;
1984 return false; 1926 return false;
1985 } 1927 }
1986 options_url_ = GetResourceURL(options_str); 1928 options_url_ = GetResourceURL(options_str);
1987 if (!options_url_.is_valid()) { 1929 if (!options_url_.is_valid()) {
1988 *error = errors::kInvalidOptionsPage; 1930 *error = errors::kInvalidOptionsPage;
1989 return false; 1931 return false;
1990 } 1932 }
1991 } 1933 }
1992 } 1934 }
1993 1935
1994 // Initialize background url (optional). 1936 // Initialize background url (optional).
1995 if (source.HasKey(keys::kBackground)) { 1937 if (manifest.HasKey(keys::kBackground)) {
1996 std::string background_str; 1938 std::string background_str;
1997 if (!source.GetString(keys::kBackground, &background_str)) { 1939 if (!manifest.GetString(keys::kBackground, &background_str)) {
1998 *error = errors::kInvalidBackground; 1940 *error = errors::kInvalidBackground;
1999 return false; 1941 return false;
2000 } 1942 }
2001 1943
2002 if (is_hosted_app()) { 1944 if (is_hosted_app()) {
2003 // Make sure "background" permission is set. 1945 // Make sure "background" permission is set.
2004 if (!api_permissions.count(ExtensionAPIPermission::kBackground)) { 1946 if (!api_permissions.count(ExtensionAPIPermission::kBackground)) {
2005 *error = errors::kBackgroundPermissionNeeded; 1947 *error = errors::kBackgroundPermissionNeeded;
2006 return false; 1948 return false;
2007 } 1949 }
(...skipping 10 matching lines...) Expand all
2018 bg_page.SchemeIs("http")))) { 1960 bg_page.SchemeIs("http")))) {
2019 *error = errors::kInvalidBackgroundInHostedApp; 1961 *error = errors::kInvalidBackgroundInHostedApp;
2020 return false; 1962 return false;
2021 } 1963 }
2022 background_url_ = bg_page; 1964 background_url_ = bg_page;
2023 } else { 1965 } else {
2024 background_url_ = GetResourceURL(background_str); 1966 background_url_ = GetResourceURL(background_str);
2025 } 1967 }
2026 } 1968 }
2027 1969
2028 if (source.HasKey(keys::kDefaultLocale)) { 1970 if (manifest.HasKey(keys::kDefaultLocale)) {
2029 if (!source.GetString(keys::kDefaultLocale, &default_locale_) || 1971 if (!manifest.GetString(keys::kDefaultLocale, &default_locale_) ||
2030 !l10n_util::IsValidLocaleSyntax(default_locale_)) { 1972 !l10n_util::IsValidLocaleSyntax(default_locale_)) {
2031 *error = errors::kInvalidDefaultLocale; 1973 *error = errors::kInvalidDefaultLocale;
2032 return false; 1974 return false;
2033 } 1975 }
2034 } 1976 }
2035 1977
2036 // Chrome URL overrides (optional) 1978 // Chrome URL overrides (optional)
2037 if (source.HasKey(keys::kChromeURLOverrides)) { 1979 if (manifest.HasKey(keys::kChromeURLOverrides)) {
2038 DictionaryValue* overrides = NULL; 1980 DictionaryValue* overrides = NULL;
2039 if (!source.GetDictionary(keys::kChromeURLOverrides, &overrides)) { 1981 if (!manifest.GetDictionary(keys::kChromeURLOverrides, &overrides)) {
2040 *error = errors::kInvalidChromeURLOverrides; 1982 *error = errors::kInvalidChromeURLOverrides;
2041 return false; 1983 return false;
2042 } 1984 }
2043 1985
2044 // Validate that the overrides are all strings 1986 // Validate that the overrides are all strings
2045 for (DictionaryValue::key_iterator iter = overrides->begin_keys(); 1987 for (DictionaryValue::key_iterator iter = overrides->begin_keys();
2046 iter != overrides->end_keys(); ++iter) { 1988 iter != overrides->end_keys(); ++iter) {
2047 std::string page = *iter; 1989 std::string page = *iter;
2048 std::string val; 1990 std::string val;
2049 // Restrict override pages to a list of supported URLs. 1991 // Restrict override pages to a list of supported URLs.
(...skipping 21 matching lines...) Expand all
2071 } 2013 }
2072 2014
2073 // An extension may override at most one page. 2015 // An extension may override at most one page.
2074 if (overrides->size() > 1) { 2016 if (overrides->size() > 1) {
2075 *error = errors::kMultipleOverrides; 2017 *error = errors::kMultipleOverrides;
2076 return false; 2018 return false;
2077 } 2019 }
2078 } 2020 }
2079 2021
2080 if (api_permissions.count(ExtensionAPIPermission::kExperimental) && 2022 if (api_permissions.count(ExtensionAPIPermission::kExperimental) &&
2081 source.HasKey(keys::kInputComponents)) { 2023 manifest.HasKey(keys::kInputComponents)) {
2082 ListValue* list_value = NULL; 2024 ListValue* list_value = NULL;
2083 if (!source.GetList(keys::kInputComponents, &list_value)) { 2025 if (!manifest.GetList(keys::kInputComponents, &list_value)) {
2084 *error = errors::kInvalidInputComponents; 2026 *error = errors::kInvalidInputComponents;
2085 return false; 2027 return false;
2086 } 2028 }
2087 2029
2088 for (size_t i = 0; i < list_value->GetSize(); ++i) { 2030 for (size_t i = 0; i < list_value->GetSize(); ++i) {
2089 DictionaryValue* module_value = NULL; 2031 DictionaryValue* module_value = NULL;
2090 std::string name_str; 2032 std::string name_str;
2091 InputComponentType type; 2033 InputComponentType type;
2092 std::string id_str; 2034 std::string id_str;
2093 std::string description_str; 2035 std::string description_str;
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2202 input_components_.back().description = description_str; 2144 input_components_.back().description = description_str;
2203 input_components_.back().language = language_str; 2145 input_components_.back().language = language_str;
2204 input_components_.back().layouts.insert(layouts.begin(), layouts.end()); 2146 input_components_.back().layouts.insert(layouts.begin(), layouts.end());
2205 input_components_.back().shortcut_keycode = shortcut_keycode_str; 2147 input_components_.back().shortcut_keycode = shortcut_keycode_str;
2206 input_components_.back().shortcut_alt = shortcut_alt; 2148 input_components_.back().shortcut_alt = shortcut_alt;
2207 input_components_.back().shortcut_ctrl = shortcut_ctrl; 2149 input_components_.back().shortcut_ctrl = shortcut_ctrl;
2208 input_components_.back().shortcut_shift = shortcut_shift; 2150 input_components_.back().shortcut_shift = shortcut_shift;
2209 } 2151 }
2210 } 2152 }
2211 2153
2212 if (source.HasKey(keys::kOmnibox)) { 2154 if (manifest.HasKey(keys::kOmnibox)) {
2213 if (!source.GetString(keys::kOmniboxKeyword, &omnibox_keyword_) || 2155 if (!manifest.GetString(keys::kOmniboxKeyword, &omnibox_keyword_) ||
2214 omnibox_keyword_.empty()) { 2156 omnibox_keyword_.empty()) {
2215 *error = errors::kInvalidOmniboxKeyword; 2157 *error = errors::kInvalidOmniboxKeyword;
2216 return false; 2158 return false;
2217 } 2159 }
2218 } 2160 }
2219 2161
2220 if (source.HasKey(keys::kContentSecurityPolicy)) { 2162 if (manifest.HasKey(keys::kContentSecurityPolicy)) {
2221 std::string content_security_policy; 2163 std::string content_security_policy;
2222 if (!source.GetString(keys::kContentSecurityPolicy, 2164 if (!manifest.GetString(keys::kContentSecurityPolicy,
2223 &content_security_policy)) { 2165 &content_security_policy)) {
2224 *error = errors::kInvalidContentSecurityPolicy; 2166 *error = errors::kInvalidContentSecurityPolicy;
2225 return false; 2167 return false;
2226 } 2168 }
2227 // We block these characters to prevent HTTP header injection when 2169 // We block these characters to prevent HTTP header injection when
2228 // representing the content security policy as an HTTP header. 2170 // representing the content security policy as an HTTP header.
2229 const char kBadCSPCharacters[] = {'\r', '\n', '\0'}; 2171 const char kBadCSPCharacters[] = {'\r', '\n', '\0'};
2230 if (content_security_policy.find_first_of(kBadCSPCharacters, 0, 2172 if (content_security_policy.find_first_of(kBadCSPCharacters, 0,
2231 arraysize(kBadCSPCharacters)) != 2173 arraysize(kBadCSPCharacters)) !=
2232 std::string::npos) { 2174 std::string::npos) {
2233 *error = errors::kInvalidContentSecurityPolicy; 2175 *error = errors::kInvalidContentSecurityPolicy;
2234 return false; 2176 return false;
2235 } 2177 }
2236 content_security_policy_ = content_security_policy; 2178 content_security_policy_ = content_security_policy;
2237 } else if (manifest_version_ >= 2) { 2179 } else if (manifest_version_ >= 2) {
2238 // Manifest version 2 introduced a default Content-Security-Policy. 2180 // Manifest version 2 introduced a default Content-Security-Policy.
2239 // TODO(abarth): Should we continue to let extensions override the 2181 // TODO(abarth): Should we continue to let extensions override the
2240 // default Content-Security-Policy? 2182 // default Content-Security-Policy?
2241 content_security_policy_ = kDefaultContentSecurityPolicy; 2183 content_security_policy_ = kDefaultContentSecurityPolicy;
2242 } 2184 }
2243 2185
2244 // Initialize devtools page url (optional). 2186 // Initialize devtools page url (optional).
2245 if (source.HasKey(keys::kDevToolsPage)) { 2187 if (manifest.HasKey(keys::kDevToolsPage)) {
2246 std::string devtools_str; 2188 std::string devtools_str;
2247 if (!source.GetString(keys::kDevToolsPage, &devtools_str)) { 2189 if (!manifest.GetString(keys::kDevToolsPage, &devtools_str)) {
2248 *error = errors::kInvalidDevToolsPage; 2190 *error = errors::kInvalidDevToolsPage;
2249 return false; 2191 return false;
2250 } 2192 }
2251 if (!api_permissions.count(ExtensionAPIPermission::kExperimental)) { 2193 if (!api_permissions.count(ExtensionAPIPermission::kExperimental)) {
2252 *error = errors::kDevToolsExperimental; 2194 *error = errors::kDevToolsExperimental;
2253 return false; 2195 return false;
2254 } 2196 }
2255 devtools_url_ = GetResourceURL(devtools_str); 2197 devtools_url_ = GetResourceURL(devtools_str);
2256 } 2198 }
2257 2199
2258 // Initialize sidebar action (optional). 2200 // Initialize sidebar action (optional).
2259 if (source.HasKey(keys::kSidebar)) { 2201 if (manifest.HasKey(keys::kSidebar)) {
2260 DictionaryValue* sidebar_value = NULL; 2202 DictionaryValue* sidebar_value = NULL;
2261 if (!source.GetDictionary(keys::kSidebar, &sidebar_value)) { 2203 if (!manifest.GetDictionary(keys::kSidebar, &sidebar_value)) {
2262 *error = errors::kInvalidSidebar; 2204 *error = errors::kInvalidSidebar;
2263 return false; 2205 return false;
2264 } 2206 }
2265 if (!api_permissions.count(ExtensionAPIPermission::kExperimental)) { 2207 if (!api_permissions.count(ExtensionAPIPermission::kExperimental)) {
2266 *error = errors::kSidebarExperimental; 2208 *error = errors::kSidebarExperimental;
2267 return false; 2209 return false;
2268 } 2210 }
2269 sidebar_defaults_.reset(LoadExtensionSidebarDefaults(sidebar_value, error)); 2211 sidebar_defaults_.reset(LoadExtensionSidebarDefaults(sidebar_value, error));
2270 if (!sidebar_defaults_.get()) 2212 if (!sidebar_defaults_.get())
2271 return false; // Failed to parse sidebar definition. 2213 return false; // Failed to parse sidebar definition.
2272 } 2214 }
2273 2215
2274 // Initialize text-to-speech voices (optional). 2216 // Initialize text-to-speech voices (optional).
2275 if (source.HasKey(keys::kTtsEngine)) { 2217 if (manifest.HasKey(keys::kTtsEngine)) {
2276 DictionaryValue* tts_dict = NULL; 2218 DictionaryValue* tts_dict = NULL;
2277 if (!source.GetDictionary(keys::kTtsEngine, &tts_dict)) { 2219 if (!manifest.GetDictionary(keys::kTtsEngine, &tts_dict)) {
2278 *error = errors::kInvalidTts; 2220 *error = errors::kInvalidTts;
2279 return false; 2221 return false;
2280 } 2222 }
2281 2223
2282 if (tts_dict->HasKey(keys::kTtsVoices)) { 2224 if (tts_dict->HasKey(keys::kTtsVoices)) {
2283 ListValue* tts_voices = NULL; 2225 ListValue* tts_voices = NULL;
2284 if (!tts_dict->GetList(keys::kTtsVoices, &tts_voices)) { 2226 if (!tts_dict->GetList(keys::kTtsVoices, &tts_voices)) {
2285 *error = errors::kInvalidTtsVoices; 2227 *error = errors::kInvalidTtsVoices;
2286 return false; 2228 return false;
2287 } 2229 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2348 voice_data.event_types.insert(event_type); 2290 voice_data.event_types.insert(event_type);
2349 } 2291 }
2350 } 2292 }
2351 2293
2352 tts_voices_.push_back(voice_data); 2294 tts_voices_.push_back(voice_data);
2353 } 2295 }
2354 } 2296 }
2355 } 2297 }
2356 2298
2357 // Initialize web intents (optional). 2299 // Initialize web intents (optional).
2358 if (!LoadWebIntentServices(source, error)) 2300 if (!LoadWebIntentServices(manifest, error))
2359 return false; 2301 return false;
2360 2302
2361 // Initialize incognito behavior. Apps default to split mode, extensions 2303 // Initialize incognito behavior. Apps default to split mode, extensions
2362 // default to spanning. 2304 // default to spanning.
2363 incognito_split_mode_ = is_app(); 2305 incognito_split_mode_ = is_app();
2364 if (source.HasKey(keys::kIncognito)) { 2306 if (manifest.HasKey(keys::kIncognito)) {
2365 std::string value; 2307 std::string value;
2366 if (!source.GetString(keys::kIncognito, &value)) { 2308 if (!manifest.GetString(keys::kIncognito, &value)) {
2367 *error = errors::kInvalidIncognitoBehavior; 2309 *error = errors::kInvalidIncognitoBehavior;
2368 return false; 2310 return false;
2369 } 2311 }
2370 if (value == values::kIncognitoSpanning) { 2312 if (value == values::kIncognitoSpanning) {
2371 incognito_split_mode_ = false; 2313 incognito_split_mode_ = false;
2372 } else if (value == values::kIncognitoSplit) { 2314 } else if (value == values::kIncognitoSplit) {
2373 incognito_split_mode_ = true; 2315 incognito_split_mode_ = true;
2374 } else { 2316 } else {
2375 *error = errors::kInvalidIncognitoBehavior; 2317 *error = errors::kInvalidIncognitoBehavior;
2376 return false; 2318 return false;
2377 } 2319 }
2378 } 2320 }
2379 2321
2380 // Initialize offline-enabled status. Defaults to false. 2322 // Initialize offline-enabled status. Defaults to false.
2381 if (source.HasKey(keys::kOfflineEnabled)) { 2323 if (manifest.HasKey(keys::kOfflineEnabled)) {
2382 if (!source.GetBoolean(keys::kOfflineEnabled, &offline_enabled_)) { 2324 if (!manifest.GetBoolean(keys::kOfflineEnabled, &offline_enabled_)) {
2383 *error = errors::kInvalidOfflineEnabled; 2325 *error = errors::kInvalidOfflineEnabled;
2384 return false; 2326 return false;
2385 } 2327 }
2386 } 2328 }
2387 2329
2388 // Initialize requirements (optional). Not actually persisted (they're only 2330 // Initialize requirements (optional). Not actually persisted (they're only
2389 // used by the store), but still validated. 2331 // used by the store), but still validated.
2390 if (source.HasKey(keys::kRequirements)) { 2332 if (manifest.HasKey(keys::kRequirements)) {
2391 DictionaryValue* requirements_value = NULL; 2333 DictionaryValue* requirements_value = NULL;
2392 if (!source.GetDictionary(keys::kRequirements, &requirements_value)) { 2334 if (!manifest.GetDictionary(keys::kRequirements, &requirements_value)) {
2393 *error = errors::kInvalidRequirements; 2335 *error = errors::kInvalidRequirements;
2394 return false; 2336 return false;
2395 } 2337 }
2396 2338
2397 for (DictionaryValue::key_iterator it = requirements_value->begin_keys(); 2339 for (DictionaryValue::key_iterator it = requirements_value->begin_keys();
2398 it != requirements_value->end_keys(); ++it) { 2340 it != requirements_value->end_keys(); ++it) {
2399 DictionaryValue* requirement_value; 2341 DictionaryValue* requirement_value;
2400 if (!requirements_value->GetDictionaryWithoutPathExpansion( 2342 if (!requirements_value->GetDictionaryWithoutPathExpansion(
2401 *it, &requirement_value)) { 2343 *it, &requirement_value)) {
2402 *error = ExtensionErrorUtils::FormatErrorMessage( 2344 *error = ExtensionErrorUtils::FormatErrorMessage(
2403 errors::kInvalidRequirement, *it); 2345 errors::kInvalidRequirement, *it);
2404 return false; 2346 return false;
2405 } 2347 }
2406 } 2348 }
2407 } 2349 }
2408 2350
2409 if (HasMultipleUISurfaces()) { 2351 if (HasMultipleUISurfaces()) {
2410 *error = errors::kOneUISurfaceOnly; 2352 *error = errors::kOneUISurfaceOnly;
2411 return false; 2353 return false;
2412 } 2354 }
2413 2355
2414 runtime_data_.SetActivePermissions(new ExtensionPermissionSet( 2356 runtime_data_.SetActivePermissions(new ExtensionPermissionSet(
2415 this, api_permissions, host_permissions)); 2357 this, api_permissions, host_permissions));
2416 required_permission_set_ = new ExtensionPermissionSet( 2358 required_permission_set_ = new ExtensionPermissionSet(
2417 this, api_permissions, host_permissions); 2359 this, api_permissions, host_permissions);
2418 optional_permission_set_ = new ExtensionPermissionSet( 2360 optional_permission_set_ = new ExtensionPermissionSet(
2419 optional_api_permissions, optional_host_permissions, URLPatternSet()); 2361 optional_api_permissions, optional_host_permissions, URLPatternSet());
2420 2362
2421 // Although |source| is passed in as a const, it's still possible to modify 2363 // Although |manifest| is passed in as a const, it's still possible to modify
2422 // it. This is dangerous since the utility process re-uses |source| after 2364 // it. This is dangerous since the utility process re-uses |manifest| after
2423 // it calls InitFromValue, passing it up to the browser process which calls 2365 // it calls InitFromValue, passing it up to the browser process which calls
2424 // InitFromValue again. As a result, we need to make sure that nobody 2366 // InitFromValue again. As a result, we need to make sure that nobody
2425 // accidentally modifies it. 2367 // accidentally modifies it.
2426 DCHECK(source.Equals(manifest_value_.get())); 2368 DCHECK(manifest.Equals(manifest_value_.get()));
2427 2369
2428 return true; 2370 return true;
2429 } 2371 }
2430 2372
2431 GURL Extension::GetHomepageURL() const { 2373 GURL Extension::GetHomepageURL() const {
2432 if (homepage_url_.is_valid()) 2374 if (homepage_url_.is_valid())
2433 return homepage_url_; 2375 return homepage_url_;
2434 2376
2435 if (!UpdatesFromGallery()) 2377 if (!UpdatesFromGallery())
2436 return GURL(); 2378 return GURL();
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
2573 2515
2574 GURL Extension::GetIconURL(int size, 2516 GURL Extension::GetIconURL(int size,
2575 ExtensionIconSet::MatchType match_type) const { 2517 ExtensionIconSet::MatchType match_type) const {
2576 std::string path = icons().Get(size, match_type); 2518 std::string path = icons().Get(size, match_type);
2577 if (path.empty()) 2519 if (path.empty())
2578 return GURL(); 2520 return GURL();
2579 else 2521 else
2580 return GetResourceURL(path); 2522 return GetResourceURL(path);
2581 } 2523 }
2582 2524
2583 bool Extension::ParsePermissions(const DictionaryValue* source, 2525 bool Extension::ParsePermissions(const ManifestValue* source,
2584 const char* key, 2526 const char* key,
2585 int flags, 2527 int flags,
2586 std::string* error, 2528 std::string* error,
2587 ExtensionAPIPermissionSet* api_permissions, 2529 ExtensionAPIPermissionSet* api_permissions,
2588 URLPatternSet* host_permissions) { 2530 URLPatternSet* host_permissions) {
2589 if (source->HasKey(key)) { 2531 if (source->HasKey(key)) {
2590 // When strict error checks are enabled, make URL pattern parsing strict. 2532 // When strict error checks are enabled, make URL pattern parsing strict.
2591 URLPattern::ParseOption parse_strictness = 2533 URLPattern::ParseOption parse_strictness =
2592 (flags & STRICT_ERROR_CHECKS ? URLPattern::ERROR_ON_PORTS 2534 (flags & STRICT_ERROR_CHECKS ? URLPattern::ERROR_ON_PORTS
2593 : URLPattern::IGNORE_PORTS); 2535 : URLPattern::IGNORE_PORTS);
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after
3052 already_disabled(false), 2994 already_disabled(false),
3053 extension(extension) {} 2995 extension(extension) {}
3054 2996
3055 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( 2997 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo(
3056 const Extension* extension, 2998 const Extension* extension,
3057 const ExtensionPermissionSet* permissions, 2999 const ExtensionPermissionSet* permissions,
3058 Reason reason) 3000 Reason reason)
3059 : reason(reason), 3001 : reason(reason),
3060 extension(extension), 3002 extension(extension),
3061 permissions(permissions) {} 3003 permissions(permissions) {}
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698