| OLD | NEW |
| 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 16 matching lines...) Expand all Loading... |
| 27 #include "chrome/common/chrome_version_info.h" | 27 #include "chrome/common/chrome_version_info.h" |
| 28 #include "chrome/common/extensions/csp_validator.h" | 28 #include "chrome/common/extensions/csp_validator.h" |
| 29 #include "chrome/common/extensions/extension_action.h" | 29 #include "chrome/common/extensions/extension_action.h" |
| 30 #include "chrome/common/extensions/extension_constants.h" | 30 #include "chrome/common/extensions/extension_constants.h" |
| 31 #include "chrome/common/extensions/extension_error_utils.h" | 31 #include "chrome/common/extensions/extension_error_utils.h" |
| 32 #include "chrome/common/extensions/extension_l10n_util.h" | 32 #include "chrome/common/extensions/extension_l10n_util.h" |
| 33 #include "chrome/common/extensions/extension_resource.h" | 33 #include "chrome/common/extensions/extension_resource.h" |
| 34 #include "chrome/common/extensions/extension_sidebar_defaults.h" | 34 #include "chrome/common/extensions/extension_sidebar_defaults.h" |
| 35 #include "chrome/common/extensions/extension_sidebar_utils.h" | 35 #include "chrome/common/extensions/extension_sidebar_utils.h" |
| 36 #include "chrome/common/extensions/file_browser_handler.h" | 36 #include "chrome/common/extensions/file_browser_handler.h" |
| 37 #include "chrome/common/extensions/manifest.h" |
| 37 #include "chrome/common/extensions/user_script.h" | 38 #include "chrome/common/extensions/user_script.h" |
| 38 #include "chrome/common/url_constants.h" | 39 #include "chrome/common/url_constants.h" |
| 39 #include "googleurl/src/url_util.h" | 40 #include "googleurl/src/url_util.h" |
| 40 #include "grit/chromium_strings.h" | 41 #include "grit/chromium_strings.h" |
| 41 #include "grit/generated_resources.h" | 42 #include "grit/generated_resources.h" |
| 42 #include "grit/theme_resources.h" | 43 #include "grit/theme_resources.h" |
| 43 #include "net/base/registry_controlled_domain.h" | 44 #include "net/base/registry_controlled_domain.h" |
| 44 #include "third_party/skia/include/core/SkBitmap.h" | 45 #include "third_party/skia/include/core/SkBitmap.h" |
| 45 #include "ui/base/l10n/l10n_util.h" | 46 #include "ui/base/l10n/l10n_util.h" |
| 46 #include "ui/base/resource/resource_bundle.h" | 47 #include "ui/base/resource/resource_bundle.h" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 static void ConvertHexadecimalToIDAlphabet(std::string* id) { | 79 static void ConvertHexadecimalToIDAlphabet(std::string* id) { |
| 79 for (size_t i = 0; i < id->size(); ++i) { | 80 for (size_t i = 0; i < id->size(); ++i) { |
| 80 int val; | 81 int val; |
| 81 if (base::HexStringToInt(id->begin() + i, id->begin() + i + 1, &val)) | 82 if (base::HexStringToInt(id->begin() + i, id->begin() + i + 1, &val)) |
| 82 (*id)[i] = val + 'a'; | 83 (*id)[i] = val + 'a'; |
| 83 else | 84 else |
| 84 (*id)[i] = 'a'; | 85 (*id)[i] = 'a'; |
| 85 } | 86 } |
| 86 } | 87 } |
| 87 | 88 |
| 88 // These keys are allowed by all crx files (apps, extensions, themes, etc). | |
| 89 static const char* kBaseCrxKeys[] = { | |
| 90 keys::kCurrentLocale, | |
| 91 keys::kDefaultLocale, | |
| 92 keys::kDescription, | |
| 93 keys::kIcons, | |
| 94 keys::kManifestVersion, | |
| 95 keys::kName, | |
| 96 keys::kPublicKey, | |
| 97 keys::kSignature, | |
| 98 keys::kUpdateURL, | |
| 99 keys::kVersion, | |
| 100 }; | |
| 101 | |
| 102 bool IsBaseCrxKey(const std::string& key) { | |
| 103 for (size_t i = 0; i < arraysize(kBaseCrxKeys); ++i) { | |
| 104 if (key == kBaseCrxKeys[i]) | |
| 105 return true; | |
| 106 } | |
| 107 | |
| 108 return false; | |
| 109 } | |
| 110 | |
| 111 // A singleton object containing global data needed by the extension objects. | 89 // A singleton object containing global data needed by the extension objects. |
| 112 class ExtensionConfig { | 90 class ExtensionConfig { |
| 113 public: | 91 public: |
| 114 static ExtensionConfig* GetInstance() { | 92 static ExtensionConfig* GetInstance() { |
| 115 return Singleton<ExtensionConfig>::get(); | 93 return Singleton<ExtensionConfig>::get(); |
| 116 } | 94 } |
| 117 | 95 |
| 118 Extension::ScriptingWhitelist* whitelist() { return &scripting_whitelist_; } | 96 Extension::ScriptingWhitelist* whitelist() { return &scripting_whitelist_; } |
| 119 | 97 |
| 120 private: | 98 private: |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 | 224 |
| 247 // static | 225 // static |
| 248 scoped_refptr<Extension> Extension::Create(const FilePath& path, | 226 scoped_refptr<Extension> Extension::Create(const FilePath& path, |
| 249 Location location, | 227 Location location, |
| 250 const DictionaryValue& value, | 228 const DictionaryValue& value, |
| 251 int flags, | 229 int flags, |
| 252 std::string* error) { | 230 std::string* error) { |
| 253 DCHECK(error); | 231 DCHECK(error); |
| 254 scoped_refptr<Extension> extension = new Extension(path, location); | 232 scoped_refptr<Extension> extension = new Extension(path, location); |
| 255 | 233 |
| 256 if (!extension->InitFromValue(value, flags, error)) | 234 if (!extension->InitFromValue(new extensions::Manifest(value.DeepCopy()), |
| 235 flags, error)) |
| 257 return NULL; | 236 return NULL; |
| 258 return extension; | 237 return extension; |
| 259 } | 238 } |
| 260 | 239 |
| 261 scoped_refptr<Extension> Extension::CreateWithId(const FilePath& path, | 240 scoped_refptr<Extension> Extension::CreateWithId(const FilePath& path, |
| 262 Location location, | 241 Location location, |
| 263 const DictionaryValue& value, | 242 const DictionaryValue& value, |
| 264 int flags, | 243 int flags, |
| 265 const std::string& explicit_id, | 244 const std::string& explicit_id, |
| 266 std::string* error) { | 245 std::string* error) { |
| (...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 893 GURL url = extension_sidebar_utils::ResolveRelativePath( | 872 GURL url = extension_sidebar_utils::ResolveRelativePath( |
| 894 default_page, this, error); | 873 default_page, this, error); |
| 895 if (!url.is_valid()) | 874 if (!url.is_valid()) |
| 896 return NULL; | 875 return NULL; |
| 897 result->set_default_page(url); | 876 result->set_default_page(url); |
| 898 } | 877 } |
| 899 | 878 |
| 900 return result.release(); | 879 return result.release(); |
| 901 } | 880 } |
| 902 | 881 |
| 903 bool Extension::ContainsNonThemeKeys(const DictionaryValue& source) const { | 882 bool Extension::LoadExtent(const extensions::Manifest* manifest, |
| 904 for (DictionaryValue::key_iterator key = source.begin_keys(); | |
| 905 key != source.end_keys(); ++key) { | |
| 906 if (!IsBaseCrxKey(*key) && *key != keys::kTheme) | |
| 907 return true; | |
| 908 } | |
| 909 return false; | |
| 910 } | |
| 911 | |
| 912 bool Extension::LoadIsApp(const DictionaryValue* manifest, | |
| 913 std::string* error) { | |
| 914 if (manifest->HasKey(keys::kApp)) | |
| 915 is_app_ = true; | |
| 916 | |
| 917 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 918 switches::kEnablePlatformApps)) { | |
| 919 if (manifest->HasKey(keys::kPlatformApp)) { | |
| 920 manifest->GetBoolean(keys::kPlatformApp, &is_platform_app_); | |
| 921 } | |
| 922 } | |
| 923 | |
| 924 return true; | |
| 925 } | |
| 926 | |
| 927 bool Extension::LoadExtent(const DictionaryValue* manifest, | |
| 928 const char* key, | 883 const char* key, |
| 929 URLPatternSet* extent, | 884 URLPatternSet* extent, |
| 930 const char* list_error, | 885 const char* list_error, |
| 931 const char* value_error, | 886 const char* value_error, |
| 932 URLPattern::ParseOption parse_strictness, | 887 URLPattern::ParseOption parse_strictness, |
| 933 std::string* error) { | 888 std::string* error) { |
| 934 Value* temp = NULL; | 889 Value* temp = NULL; |
| 935 if (!manifest->Get(key, &temp)) | 890 if (!manifest->Get(key, &temp)) |
| 936 return true; | 891 return true; |
| 937 | 892 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 994 return false; | 949 return false; |
| 995 } | 950 } |
| 996 pattern.SetPath(pattern.path() + '*'); | 951 pattern.SetPath(pattern.path() + '*'); |
| 997 | 952 |
| 998 extent->AddPattern(pattern); | 953 extent->AddPattern(pattern); |
| 999 } | 954 } |
| 1000 | 955 |
| 1001 return true; | 956 return true; |
| 1002 } | 957 } |
| 1003 | 958 |
| 1004 bool Extension::LoadLaunchURL(const DictionaryValue* manifest, | 959 bool Extension::LoadLaunchURL(const extensions::Manifest* manifest, |
| 1005 std::string* error) { | 960 std::string* error) { |
| 1006 Value* temp = NULL; | 961 Value* temp = NULL; |
| 1007 | 962 |
| 1008 // launch URL can be either local (to chrome-extension:// root) or an absolute | 963 // launch URL can be either local (to chrome-extension:// root) or an absolute |
| 1009 // web URL. | 964 // web URL. |
| 1010 if (manifest->Get(keys::kLaunchLocalPath, &temp)) { | 965 if (manifest->Get(keys::kLaunchLocalPath, &temp)) { |
| 1011 if (manifest->Get(keys::kLaunchWebURL, NULL)) { | 966 if (manifest->Get(keys::kLaunchWebURL, NULL)) { |
| 1012 *error = errors::kLaunchPathAndURLAreExclusive; | 967 *error = errors::kLaunchPathAndURLAreExclusive; |
| 1013 return false; | 968 return false; |
| 1014 } | 969 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1092 GURL::Replacements replacements; | 1047 GURL::Replacements replacements; |
| 1093 replacements.SetPathStr(path); | 1048 replacements.SetPathStr(path); |
| 1094 GURL cloud_print_enable_connector_url = | 1049 GURL cloud_print_enable_connector_url = |
| 1095 cloud_print_service_url.ReplaceComponents(replacements); | 1050 cloud_print_service_url.ReplaceComponents(replacements); |
| 1096 OverrideLaunchUrl(cloud_print_enable_connector_url); | 1051 OverrideLaunchUrl(cloud_print_enable_connector_url); |
| 1097 } | 1052 } |
| 1098 } | 1053 } |
| 1099 return true; | 1054 return true; |
| 1100 } | 1055 } |
| 1101 | 1056 |
| 1102 bool Extension::LoadLaunchContainer(const DictionaryValue* manifest, | 1057 bool Extension::LoadLaunchContainer(const extensions::Manifest* manifest, |
| 1103 std::string* error) { | 1058 std::string* error) { |
| 1104 Value* temp = NULL; | 1059 Value* temp = NULL; |
| 1105 if (!manifest->Get(keys::kLaunchContainer, &temp)) | 1060 if (!manifest->Get(keys::kLaunchContainer, &temp)) |
| 1106 return true; | 1061 return true; |
| 1107 | 1062 |
| 1108 std::string launch_container_string; | 1063 std::string launch_container_string; |
| 1109 if (!temp->GetAsString(&launch_container_string)) { | 1064 if (!temp->GetAsString(&launch_container_string)) { |
| 1110 *error = errors::kInvalidLaunchContainer; | 1065 *error = errors::kInvalidLaunchContainer; |
| 1111 return false; | 1066 return false; |
| 1112 } | 1067 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1147 if (!temp->GetAsInteger(&launch_height_) || launch_height_ < 0) { | 1102 if (!temp->GetAsInteger(&launch_height_) || launch_height_ < 0) { |
| 1148 launch_height_ = 0; | 1103 launch_height_ = 0; |
| 1149 *error = errors::kInvalidLaunchHeight; | 1104 *error = errors::kInvalidLaunchHeight; |
| 1150 return false; | 1105 return false; |
| 1151 } | 1106 } |
| 1152 } | 1107 } |
| 1153 | 1108 |
| 1154 return true; | 1109 return true; |
| 1155 } | 1110 } |
| 1156 | 1111 |
| 1157 bool Extension::LoadAppIsolation(const DictionaryValue* manifest, | 1112 bool Extension::LoadAppIsolation(const extensions::Manifest* manifest, |
| 1158 std::string* error) { | 1113 std::string* error) { |
| 1159 Value* temp = NULL; | 1114 Value* temp = NULL; |
| 1160 if (!manifest->Get(keys::kIsolation, &temp)) | 1115 if (!manifest->Get(keys::kIsolation, &temp)) |
| 1161 return true; | 1116 return true; |
| 1162 | 1117 |
| 1163 if (temp->GetType() != Value::TYPE_LIST) { | 1118 if (temp->GetType() != Value::TYPE_LIST) { |
| 1164 *error = errors::kInvalidIsolation; | 1119 *error = errors::kInvalidIsolation; |
| 1165 return false; | 1120 return false; |
| 1166 } | 1121 } |
| 1167 | 1122 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1179 if (isolation_string == values::kIsolatedStorage) { | 1134 if (isolation_string == values::kIsolatedStorage) { |
| 1180 is_storage_isolated_ = true; | 1135 is_storage_isolated_ = true; |
| 1181 } else { | 1136 } else { |
| 1182 DLOG(WARNING) << "Did not recognize isolation type: " | 1137 DLOG(WARNING) << "Did not recognize isolation type: " |
| 1183 << isolation_string; | 1138 << isolation_string; |
| 1184 } | 1139 } |
| 1185 } | 1140 } |
| 1186 return true; | 1141 return true; |
| 1187 } | 1142 } |
| 1188 | 1143 |
| 1189 bool Extension::LoadWebIntentServices(const base::DictionaryValue& manifest, | 1144 bool Extension::LoadWebIntentServices(const extensions::Manifest* manifest, |
| 1190 std::string* error) { | 1145 std::string* error) { |
| 1191 DCHECK(error); | 1146 DCHECK(error); |
| 1192 | 1147 |
| 1193 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableWebIntents)) | 1148 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableWebIntents)) |
| 1194 return true; | 1149 return true; |
| 1195 | 1150 |
| 1196 if (!manifest.HasKey(keys::kIntents)) | 1151 if (!manifest->HasKey(keys::kIntents)) |
| 1197 return true; | 1152 return true; |
| 1198 | 1153 |
| 1199 DictionaryValue* all_services = NULL; | 1154 DictionaryValue* all_services = NULL; |
| 1200 if (!manifest.GetDictionary(keys::kIntents, &all_services)) { | 1155 if (!manifest->GetDictionary(keys::kIntents, &all_services)) { |
| 1201 *error = errors::kInvalidIntents; | 1156 *error = errors::kInvalidIntents; |
| 1202 return false; | 1157 return false; |
| 1203 } | 1158 } |
| 1204 | 1159 |
| 1205 std::string value; | 1160 std::string value; |
| 1206 for (DictionaryValue::key_iterator iter(all_services->begin_keys()); | 1161 for (DictionaryValue::key_iterator iter(all_services->begin_keys()); |
| 1207 iter != all_services->end_keys(); ++iter) { | 1162 iter != all_services->end_keys(); ++iter) { |
| 1208 webkit_glue::WebIntentServiceData service; | 1163 webkit_glue::WebIntentServiceData service; |
| 1209 | 1164 |
| 1210 DictionaryValue* one_service = NULL; | 1165 DictionaryValue* one_service = NULL; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1249 service.disposition = | 1204 service.disposition = |
| 1250 webkit_glue::WebIntentServiceData::DISPOSITION_WINDOW; | 1205 webkit_glue::WebIntentServiceData::DISPOSITION_WINDOW; |
| 1251 } | 1206 } |
| 1252 } | 1207 } |
| 1253 | 1208 |
| 1254 intents_services_.push_back(service); | 1209 intents_services_.push_back(service); |
| 1255 } | 1210 } |
| 1256 return true; | 1211 return true; |
| 1257 } | 1212 } |
| 1258 | 1213 |
| 1259 | |
| 1260 bool Extension::EnsureNotHybridApp(const DictionaryValue* manifest, | |
| 1261 std::string* error) { | |
| 1262 if (web_extent().is_empty()) | |
| 1263 return true; | |
| 1264 | |
| 1265 for (DictionaryValue::key_iterator key = manifest->begin_keys(); | |
| 1266 key != manifest->end_keys(); ++key) { | |
| 1267 if (!IsBaseCrxKey(*key) && | |
| 1268 *key != keys::kApp && | |
| 1269 *key != keys::kPermissions && | |
| 1270 *key != keys::kOptionalPermissions && | |
| 1271 *key != keys::kOptionsPage && | |
| 1272 *key != keys::kBackground && | |
| 1273 *key != keys::kOfflineEnabled && | |
| 1274 *key != keys::kMinimumChromeVersion && | |
| 1275 *key != keys::kRequirements) { | |
| 1276 *error = ExtensionErrorUtils::FormatErrorMessage( | |
| 1277 errors::kHostedAppsCannotIncludeExtensionFeatures, *key); | |
| 1278 return false; | |
| 1279 } | |
| 1280 } | |
| 1281 | |
| 1282 return true; | |
| 1283 } | |
| 1284 | |
| 1285 // static | 1214 // static |
| 1286 bool Extension::IsTrustedId(const std::string& id) { | 1215 bool Extension::IsTrustedId(const std::string& id) { |
| 1287 // See http://b/4946060 for more details. | 1216 // See http://b/4946060 for more details. |
| 1288 return id == std::string("nckgahadagoaajjgafhacjanaoiihapd"); | 1217 return id == std::string("nckgahadagoaajjgafhacjanaoiihapd"); |
| 1289 } | 1218 } |
| 1290 | 1219 |
| 1291 Extension::Extension(const FilePath& path, Location location) | 1220 Extension::Extension(const FilePath& path, Location location) |
| 1292 : manifest_version_(0), | 1221 : manifest_version_(0), |
| 1293 incognito_split_mode_(false), | 1222 incognito_split_mode_(false), |
| 1294 offline_enabled_(false), | 1223 offline_enabled_(false), |
| 1295 location_(location), | 1224 location_(location), |
| 1296 converted_from_user_script_(false), | 1225 converted_from_user_script_(false), |
| 1297 is_theme_(false), | |
| 1298 is_app_(false), | |
| 1299 is_platform_app_(false), | |
| 1300 is_storage_isolated_(false), | 1226 is_storage_isolated_(false), |
| 1301 launch_container_(extension_misc::LAUNCH_TAB), | 1227 launch_container_(extension_misc::LAUNCH_TAB), |
| 1302 launch_width_(0), | 1228 launch_width_(0), |
| 1303 launch_height_(0), | 1229 launch_height_(0), |
| 1304 wants_file_access_(false), | 1230 wants_file_access_(false), |
| 1305 creation_flags_(0) { | 1231 creation_flags_(0) { |
| 1306 DCHECK(path.empty() || path.IsAbsolute()); | 1232 DCHECK(path.empty() || path.IsAbsolute()); |
| 1307 path_ = MaybeNormalizePath(path); | 1233 path_ = MaybeNormalizePath(path); |
| 1308 } | 1234 } |
| 1309 | 1235 |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1448 return *ResourceBundle::GetSharedInstance().GetBitmapNamed( | 1374 return *ResourceBundle::GetSharedInstance().GetBitmapNamed( |
| 1449 IDR_EXTENSION_DEFAULT_ICON); | 1375 IDR_EXTENSION_DEFAULT_ICON); |
| 1450 } | 1376 } |
| 1451 } | 1377 } |
| 1452 | 1378 |
| 1453 GURL Extension::GetBaseURLFromExtensionId(const std::string& extension_id) { | 1379 GURL Extension::GetBaseURLFromExtensionId(const std::string& extension_id) { |
| 1454 return GURL(std::string(chrome::kExtensionScheme) + | 1380 return GURL(std::string(chrome::kExtensionScheme) + |
| 1455 chrome::kStandardSchemeSeparator + extension_id + "/"); | 1381 chrome::kStandardSchemeSeparator + extension_id + "/"); |
| 1456 } | 1382 } |
| 1457 | 1383 |
| 1458 bool Extension::InitFromValue(const DictionaryValue& source, int flags, | 1384 bool Extension::InitFromValue(extensions::Manifest* manifest, int flags, |
| 1459 std::string* error) { | 1385 std::string* error) { |
| 1460 DCHECK(error); | 1386 DCHECK(error); |
| 1461 base::AutoLock auto_lock(runtime_data_lock_); | 1387 base::AutoLock auto_lock(runtime_data_lock_); |
| 1388 |
| 1389 if (!manifest->ValidateManifest(error)) |
| 1390 return false; |
| 1391 |
| 1462 // When strict error checks are enabled, make URL pattern parsing strict. | 1392 // When strict error checks are enabled, make URL pattern parsing strict. |
| 1463 URLPattern::ParseOption parse_strictness = | 1393 URLPattern::ParseOption parse_strictness = |
| 1464 (flags & STRICT_ERROR_CHECKS ? URLPattern::ERROR_ON_PORTS | 1394 (flags & STRICT_ERROR_CHECKS ? URLPattern::ERROR_ON_PORTS |
| 1465 : URLPattern::IGNORE_PORTS); | 1395 : URLPattern::IGNORE_PORTS); |
| 1466 | 1396 |
| 1467 // Initialize permissions with an empty, default permission set. | 1397 // Initialize permissions with an empty, default permission set. |
| 1468 runtime_data_.SetActivePermissions(new ExtensionPermissionSet()); | 1398 runtime_data_.SetActivePermissions(new ExtensionPermissionSet()); |
| 1469 optional_permission_set_ = new ExtensionPermissionSet(); | 1399 optional_permission_set_ = new ExtensionPermissionSet(); |
| 1470 required_permission_set_ = new ExtensionPermissionSet(); | 1400 required_permission_set_ = new ExtensionPermissionSet(); |
| 1471 | 1401 |
| 1472 if (source.HasKey(keys::kManifestVersion)) { | 1402 if (manifest->HasKey(keys::kManifestVersion)) { |
| 1473 int manifest_version = 0; | 1403 int manifest_version = 0; |
| 1474 if (!source.GetInteger(keys::kManifestVersion, &manifest_version) || | 1404 if (!manifest->GetInteger(keys::kManifestVersion, &manifest_version) || |
| 1475 manifest_version < 1) { | 1405 manifest_version < 1) { |
| 1476 *error = errors::kInvalidManifestVersion; | 1406 *error = errors::kInvalidManifestVersion; |
| 1477 return false; | 1407 return false; |
| 1478 } | 1408 } |
| 1479 manifest_version_ = manifest_version; | 1409 manifest_version_ = manifest_version; |
| 1480 } else { | 1410 } else { |
| 1481 // Version 1 was the original version, which lacked a version indicator. | 1411 // Version 1 was the original version, which lacked a version indicator. |
| 1482 manifest_version_ = 1; | 1412 manifest_version_ = 1; |
| 1483 } | 1413 } |
| 1484 | 1414 |
| 1485 if (flags & REQUIRE_MODERN_MANIFEST_VERSION && | 1415 if (flags & REQUIRE_MODERN_MANIFEST_VERSION && |
| 1486 manifest_version() < kModernManifestVersion && | 1416 manifest_version() < kModernManifestVersion && |
| 1487 !CommandLine::ForCurrentProcess()->HasSwitch( | 1417 !CommandLine::ForCurrentProcess()->HasSwitch( |
| 1488 switches::kAllowLegacyExtensionManifests)) { | 1418 switches::kAllowLegacyExtensionManifests)) { |
| 1489 *error = errors::kInvalidManifestVersion; | 1419 *error = errors::kInvalidManifestVersion; |
| 1490 return false; | 1420 return false; |
| 1491 } | 1421 } |
| 1492 | 1422 |
| 1493 if (source.HasKey(keys::kPublicKey)) { | 1423 if (manifest->HasKey(keys::kPublicKey)) { |
| 1494 std::string public_key_bytes; | 1424 std::string public_key_bytes; |
| 1495 if (!source.GetString(keys::kPublicKey, | 1425 if (!manifest->GetString(keys::kPublicKey, |
| 1496 &public_key_) || | 1426 &public_key_) || |
| 1497 !ParsePEMKeyBytes(public_key_, | 1427 !ParsePEMKeyBytes(public_key_, |
| 1498 &public_key_bytes) || | 1428 &public_key_bytes) || |
| 1499 !GenerateId(public_key_bytes, &id_)) { | 1429 !GenerateId(public_key_bytes, &id_)) { |
| 1500 *error = errors::kInvalidKey; | 1430 *error = errors::kInvalidKey; |
| 1501 return false; | 1431 return false; |
| 1502 } | 1432 } |
| 1503 } else if (flags & REQUIRE_KEY) { | 1433 } else if (flags & REQUIRE_KEY) { |
| 1504 *error = errors::kInvalidKey; | 1434 *error = errors::kInvalidKey; |
| 1505 return false; | 1435 return false; |
| 1506 } else { | 1436 } else { |
| 1507 // If there is a path, we generate the ID from it. This is useful for | 1437 // If there is a path, we generate the ID from it. This is useful for |
| 1508 // development mode, because it keeps the ID stable across restarts and | 1438 // development mode, because it keeps the ID stable across restarts and |
| 1509 // reloading the extension. | 1439 // reloading the extension. |
| 1510 id_ = Extension::GenerateIdForPath(path()); | 1440 id_ = Extension::GenerateIdForPath(path()); |
| 1511 if (id_.empty()) { | 1441 if (id_.empty()) { |
| 1512 NOTREACHED() << "Could not create ID from path."; | 1442 NOTREACHED() << "Could not create ID from path."; |
| 1513 return false; | 1443 return false; |
| 1514 } | 1444 } |
| 1515 } | 1445 } |
| 1516 | 1446 |
| 1517 creation_flags_ = flags; | 1447 creation_flags_ = flags; |
| 1518 | 1448 |
| 1519 // Make a copy of the manifest so we can store it in prefs. | 1449 manifest_.reset(manifest); |
| 1520 manifest_value_.reset(source.DeepCopy()); | |
| 1521 | 1450 |
| 1522 // Initialize the URL. | 1451 // Initialize the URL. |
| 1523 extension_url_ = Extension::GetBaseURLFromExtensionId(id()); | 1452 extension_url_ = Extension::GetBaseURLFromExtensionId(id()); |
| 1524 | 1453 |
| 1525 // Initialize version. | 1454 // Initialize version. |
| 1526 std::string version_str; | 1455 std::string version_str; |
| 1527 if (!source.GetString(keys::kVersion, &version_str)) { | 1456 if (!manifest->GetString(keys::kVersion, &version_str)) { |
| 1528 *error = errors::kInvalidVersion; | 1457 *error = errors::kInvalidVersion; |
| 1529 return false; | 1458 return false; |
| 1530 } | 1459 } |
| 1531 version_.reset(Version::GetVersionFromString(version_str)); | 1460 version_.reset(Version::GetVersionFromString(version_str)); |
| 1532 if (!version_.get() || | 1461 if (!version_.get() || |
| 1533 version_->components().size() > 4) { | 1462 version_->components().size() > 4) { |
| 1534 *error = errors::kInvalidVersion; | 1463 *error = errors::kInvalidVersion; |
| 1535 return false; | 1464 return false; |
| 1536 } | 1465 } |
| 1537 | 1466 |
| 1538 // Initialize name. | 1467 // Initialize name. |
| 1539 string16 localized_name; | 1468 string16 localized_name; |
| 1540 if (!source.GetString(keys::kName, &localized_name)) { | 1469 if (!manifest->GetString(keys::kName, &localized_name)) { |
| 1541 *error = errors::kInvalidName; | 1470 *error = errors::kInvalidName; |
| 1542 return false; | 1471 return false; |
| 1543 } | 1472 } |
| 1544 base::i18n::AdjustStringForLocaleDirection(&localized_name); | 1473 base::i18n::AdjustStringForLocaleDirection(&localized_name); |
| 1545 name_ = UTF16ToUTF8(localized_name); | 1474 name_ = UTF16ToUTF8(localized_name); |
| 1546 | 1475 |
| 1547 // Load App settings. LoadExtent at least has to be done before | 1476 // Load App settings. LoadExtent at least has to be done before |
| 1548 // ParsePermissions(), because the valid permissions depend on what type of | 1477 // ParsePermissions(), because the valid permissions depend on what type of |
| 1549 // package this is. | 1478 // package this is. |
| 1550 if (!LoadIsApp(manifest_value_.get(), error) || | 1479 if (is_app() && |
| 1551 !LoadExtent(manifest_value_.get(), keys::kWebURLs, | 1480 (!LoadExtent(manifest_.get(), keys::kWebURLs, |
| 1552 &extent_, | 1481 &extent_, |
| 1553 errors::kInvalidWebURLs, errors::kInvalidWebURL, | 1482 errors::kInvalidWebURLs, errors::kInvalidWebURL, |
| 1554 parse_strictness, error) || | 1483 parse_strictness, error) || |
| 1555 !EnsureNotHybridApp(manifest_value_.get(), error) || | 1484 !LoadLaunchURL(manifest_.get(), error) || |
| 1556 !LoadLaunchURL(manifest_value_.get(), error) || | 1485 !LoadLaunchContainer(manifest_.get(), error))) { |
| 1557 !LoadLaunchContainer(manifest_value_.get(), error)) { | |
| 1558 return false; | 1486 return false; |
| 1559 } | 1487 } |
| 1560 | 1488 |
| 1561 if (is_platform_app_) { | 1489 if (is_platform_app()) { |
| 1562 if (launch_container() != extension_misc::LAUNCH_SHELL) { | 1490 if (launch_container() != extension_misc::LAUNCH_SHELL) { |
| 1563 *error = errors::kInvalidLaunchContainerForPlatform; | 1491 *error = errors::kInvalidLaunchContainerForPlatform; |
| 1564 return false; | 1492 return false; |
| 1565 } | 1493 } |
| 1566 } else if (launch_container() == extension_misc::LAUNCH_SHELL) { | 1494 } else if (launch_container() == extension_misc::LAUNCH_SHELL) { |
| 1567 *error = errors::kInvalidLaunchContainerForNonPlatform; | 1495 *error = errors::kInvalidLaunchContainerForNonPlatform; |
| 1568 return false; | 1496 return false; |
| 1569 } | 1497 } |
| 1570 | 1498 |
| 1571 // Initialize the permissions (optional). | 1499 // Initialize the permissions (optional). |
| 1572 ExtensionAPIPermissionSet api_permissions; | 1500 ExtensionAPIPermissionSet api_permissions; |
| 1573 URLPatternSet host_permissions; | 1501 URLPatternSet host_permissions; |
| 1574 if (!ParsePermissions(&source, | 1502 if (!ParsePermissions(manifest_.get(), |
| 1575 keys::kPermissions, | 1503 keys::kPermissions, |
| 1576 flags, | 1504 flags, |
| 1577 error, | 1505 error, |
| 1578 &api_permissions, | 1506 &api_permissions, |
| 1579 &host_permissions)) { | 1507 &host_permissions)) { |
| 1580 return false; | 1508 return false; |
| 1581 } | 1509 } |
| 1582 | 1510 |
| 1583 // Initialize the optional permissions (optional). | 1511 // Initialize the optional permissions (optional). |
| 1584 ExtensionAPIPermissionSet optional_api_permissions; | 1512 ExtensionAPIPermissionSet optional_api_permissions; |
| 1585 URLPatternSet optional_host_permissions; | 1513 URLPatternSet optional_host_permissions; |
| 1586 if (!ParsePermissions(&source, | 1514 if (!ParsePermissions(manifest_.get(), |
| 1587 keys::kOptionalPermissions, | 1515 keys::kOptionalPermissions, |
| 1588 flags, | 1516 flags, |
| 1589 error, | 1517 error, |
| 1590 &optional_api_permissions, | 1518 &optional_api_permissions, |
| 1591 &optional_host_permissions)) { | 1519 &optional_host_permissions)) { |
| 1592 return false; | 1520 return false; |
| 1593 } | 1521 } |
| 1594 | 1522 |
| 1595 // Initialize description (if present). | 1523 // Initialize description (if present). |
| 1596 if (source.HasKey(keys::kDescription)) { | 1524 if (manifest->HasKey(keys::kDescription)) { |
| 1597 if (!source.GetString(keys::kDescription, | 1525 if (!manifest->GetString(keys::kDescription, |
| 1598 &description_)) { | 1526 &description_)) { |
| 1599 *error = errors::kInvalidDescription; | 1527 *error = errors::kInvalidDescription; |
| 1600 return false; | 1528 return false; |
| 1601 } | 1529 } |
| 1602 } | 1530 } |
| 1603 | 1531 |
| 1604 // Initialize homepage url (if present). | 1532 // Initialize homepage url (if present). |
| 1605 if (source.HasKey(keys::kHomepageURL)) { | 1533 if (manifest->HasKey(keys::kHomepageURL)) { |
| 1606 std::string tmp; | 1534 std::string tmp; |
| 1607 if (!source.GetString(keys::kHomepageURL, &tmp)) { | 1535 if (!manifest->GetString(keys::kHomepageURL, &tmp)) { |
| 1608 *error = ExtensionErrorUtils::FormatErrorMessage( | 1536 *error = ExtensionErrorUtils::FormatErrorMessage( |
| 1609 errors::kInvalidHomepageURL, ""); | 1537 errors::kInvalidHomepageURL, ""); |
| 1610 return false; | 1538 return false; |
| 1611 } | 1539 } |
| 1612 homepage_url_ = GURL(tmp); | 1540 homepage_url_ = GURL(tmp); |
| 1613 if (!homepage_url_.is_valid() || | 1541 if (!homepage_url_.is_valid() || |
| 1614 (!homepage_url_.SchemeIs("http") && | 1542 (!homepage_url_.SchemeIs("http") && |
| 1615 !homepage_url_.SchemeIs("https"))) { | 1543 !homepage_url_.SchemeIs("https"))) { |
| 1616 *error = ExtensionErrorUtils::FormatErrorMessage( | 1544 *error = ExtensionErrorUtils::FormatErrorMessage( |
| 1617 errors::kInvalidHomepageURL, tmp); | 1545 errors::kInvalidHomepageURL, tmp); |
| 1618 return false; | 1546 return false; |
| 1619 } | 1547 } |
| 1620 } | 1548 } |
| 1621 | 1549 |
| 1622 // Initialize update url (if present). | 1550 // Initialize update url (if present). |
| 1623 if (source.HasKey(keys::kUpdateURL)) { | 1551 if (manifest->HasKey(keys::kUpdateURL)) { |
| 1624 std::string tmp; | 1552 std::string tmp; |
| 1625 if (!source.GetString(keys::kUpdateURL, &tmp)) { | 1553 if (!manifest->GetString(keys::kUpdateURL, &tmp)) { |
| 1626 *error = ExtensionErrorUtils::FormatErrorMessage( | 1554 *error = ExtensionErrorUtils::FormatErrorMessage( |
| 1627 errors::kInvalidUpdateURL, ""); | 1555 errors::kInvalidUpdateURL, ""); |
| 1628 return false; | 1556 return false; |
| 1629 } | 1557 } |
| 1630 update_url_ = GURL(tmp); | 1558 update_url_ = GURL(tmp); |
| 1631 if (!update_url_.is_valid() || | 1559 if (!update_url_.is_valid() || |
| 1632 update_url_.has_ref()) { | 1560 update_url_.has_ref()) { |
| 1633 *error = ExtensionErrorUtils::FormatErrorMessage( | 1561 *error = ExtensionErrorUtils::FormatErrorMessage( |
| 1634 errors::kInvalidUpdateURL, tmp); | 1562 errors::kInvalidUpdateURL, tmp); |
| 1635 return false; | 1563 return false; |
| 1636 } | 1564 } |
| 1637 } | 1565 } |
| 1638 | 1566 |
| 1639 // Validate minimum Chrome version (if present). We don't need to store this, | 1567 // Validate minimum Chrome version (if present). We don't need to store this, |
| 1640 // since the extension is not valid if it is incorrect. | 1568 // since the extension is not valid if it is incorrect. |
| 1641 if (source.HasKey(keys::kMinimumChromeVersion)) { | 1569 if (manifest->HasKey(keys::kMinimumChromeVersion)) { |
| 1642 std::string minimum_version_string; | 1570 std::string minimum_version_string; |
| 1643 if (!source.GetString(keys::kMinimumChromeVersion, | 1571 if (!manifest->GetString(keys::kMinimumChromeVersion, |
| 1644 &minimum_version_string)) { | 1572 &minimum_version_string)) { |
| 1645 *error = errors::kInvalidMinimumChromeVersion; | 1573 *error = errors::kInvalidMinimumChromeVersion; |
| 1646 return false; | 1574 return false; |
| 1647 } | 1575 } |
| 1648 | 1576 |
| 1649 scoped_ptr<Version> minimum_version( | 1577 scoped_ptr<Version> minimum_version( |
| 1650 Version::GetVersionFromString(minimum_version_string)); | 1578 Version::GetVersionFromString(minimum_version_string)); |
| 1651 if (!minimum_version.get()) { | 1579 if (!minimum_version.get()) { |
| 1652 *error = errors::kInvalidMinimumChromeVersion; | 1580 *error = errors::kInvalidMinimumChromeVersion; |
| 1653 return false; | 1581 return false; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1669 if (current_version->CompareTo(*minimum_version) < 0) { | 1597 if (current_version->CompareTo(*minimum_version) < 0) { |
| 1670 *error = ExtensionErrorUtils::FormatErrorMessage( | 1598 *error = ExtensionErrorUtils::FormatErrorMessage( |
| 1671 errors::kChromeVersionTooLow, | 1599 errors::kChromeVersionTooLow, |
| 1672 l10n_util::GetStringUTF8(IDS_PRODUCT_NAME), | 1600 l10n_util::GetStringUTF8(IDS_PRODUCT_NAME), |
| 1673 minimum_version_string); | 1601 minimum_version_string); |
| 1674 return false; | 1602 return false; |
| 1675 } | 1603 } |
| 1676 } | 1604 } |
| 1677 | 1605 |
| 1678 // Initialize converted_from_user_script (if present) | 1606 // Initialize converted_from_user_script (if present) |
| 1679 source.GetBoolean(keys::kConvertedFromUserScript, | 1607 if (manifest->HasKey(keys::kConvertedFromUserScript)) |
| 1680 &converted_from_user_script_); | 1608 manifest->GetBoolean(keys::kConvertedFromUserScript, |
| 1609 &converted_from_user_script_); |
| 1681 | 1610 |
| 1682 // Initialize icons (if present). | 1611 // Initialize icons (if present). |
| 1683 if (source.HasKey(keys::kIcons)) { | 1612 if (manifest->HasKey(keys::kIcons)) { |
| 1684 DictionaryValue* icons_value = NULL; | 1613 DictionaryValue* icons_value = NULL; |
| 1685 if (!source.GetDictionary(keys::kIcons, &icons_value)) { | 1614 if (!manifest->GetDictionary(keys::kIcons, &icons_value)) { |
| 1686 *error = errors::kInvalidIcons; | 1615 *error = errors::kInvalidIcons; |
| 1687 return false; | 1616 return false; |
| 1688 } | 1617 } |
| 1689 | 1618 |
| 1690 for (size_t i = 0; i < arraysize(kIconSizes); ++i) { | 1619 for (size_t i = 0; i < arraysize(kIconSizes); ++i) { |
| 1691 std::string key = base::IntToString(kIconSizes[i]); | 1620 std::string key = base::IntToString(kIconSizes[i]); |
| 1692 if (icons_value->HasKey(key)) { | 1621 if (icons_value->HasKey(key)) { |
| 1693 std::string icon_path; | 1622 std::string icon_path; |
| 1694 if (!icons_value->GetString(key, &icon_path)) { | 1623 if (!icons_value->GetString(key, &icon_path)) { |
| 1695 *error = ExtensionErrorUtils::FormatErrorMessage( | 1624 *error = ExtensionErrorUtils::FormatErrorMessage( |
| 1696 errors::kInvalidIconPath, key); | 1625 errors::kInvalidIconPath, key); |
| 1697 return false; | 1626 return false; |
| 1698 } | 1627 } |
| 1699 | 1628 |
| 1700 if (!icon_path.empty() && icon_path[0] == '/') | 1629 if (!icon_path.empty() && icon_path[0] == '/') |
| 1701 icon_path = icon_path.substr(1); | 1630 icon_path = icon_path.substr(1); |
| 1702 | 1631 |
| 1703 if (icon_path.empty()) { | 1632 if (icon_path.empty()) { |
| 1704 *error = ExtensionErrorUtils::FormatErrorMessage( | 1633 *error = ExtensionErrorUtils::FormatErrorMessage( |
| 1705 errors::kInvalidIconPath, key); | 1634 errors::kInvalidIconPath, key); |
| 1706 return false; | 1635 return false; |
| 1707 } | 1636 } |
| 1708 | 1637 |
| 1709 icons_.Add(kIconSizes[i], icon_path); | 1638 icons_.Add(kIconSizes[i], icon_path); |
| 1710 } | 1639 } |
| 1711 } | 1640 } |
| 1712 } | 1641 } |
| 1713 | 1642 |
| 1714 // Initialize themes (if present). | 1643 // Initialize themes (if present). |
| 1715 is_theme_ = false; | 1644 if (manifest->HasKey(keys::kTheme)) { |
| 1716 if (source.HasKey(keys::kTheme)) { | 1645 DictionaryValue* theme_value = NULL; |
| 1717 // Themes cannot contain extension keys. | 1646 if (!manifest->GetDictionary(keys::kTheme, &theme_value)) { |
| 1718 if (ContainsNonThemeKeys(source)) { | 1647 *error = errors::kInvalidTheme; |
| 1719 *error = errors::kThemesCannotContainExtensions; | |
| 1720 return false; | 1648 return false; |
| 1721 } | 1649 } |
| 1722 | 1650 |
| 1723 DictionaryValue* theme_value = NULL; | |
| 1724 if (!source.GetDictionary(keys::kTheme, &theme_value)) { | |
| 1725 *error = errors::kInvalidTheme; | |
| 1726 return false; | |
| 1727 } | |
| 1728 is_theme_ = true; | |
| 1729 | |
| 1730 DictionaryValue* images_value = NULL; | 1651 DictionaryValue* images_value = NULL; |
| 1731 if (theme_value->GetDictionary(keys::kThemeImages, &images_value)) { | 1652 if (theme_value->GetDictionary(keys::kThemeImages, &images_value)) { |
| 1732 // Validate that the images are all strings | 1653 // Validate that the images are all strings |
| 1733 for (DictionaryValue::key_iterator iter = images_value->begin_keys(); | 1654 for (DictionaryValue::key_iterator iter = images_value->begin_keys(); |
| 1734 iter != images_value->end_keys(); ++iter) { | 1655 iter != images_value->end_keys(); ++iter) { |
| 1735 std::string val; | 1656 std::string val; |
| 1736 if (!images_value->GetString(*iter, &val)) { | 1657 if (!images_value->GetString(*iter, &val)) { |
| 1737 *error = errors::kInvalidThemeImages; | 1658 *error = errors::kInvalidThemeImages; |
| 1738 return false; | 1659 return false; |
| 1739 } | 1660 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1791 if (theme_value->GetDictionary(keys::kThemeDisplayProperties, | 1712 if (theme_value->GetDictionary(keys::kThemeDisplayProperties, |
| 1792 &display_properties_value)) { | 1713 &display_properties_value)) { |
| 1793 theme_display_properties_.reset( | 1714 theme_display_properties_.reset( |
| 1794 display_properties_value->DeepCopy()); | 1715 display_properties_value->DeepCopy()); |
| 1795 } | 1716 } |
| 1796 | 1717 |
| 1797 return true; | 1718 return true; |
| 1798 } | 1719 } |
| 1799 | 1720 |
| 1800 // Initialize plugins (optional). | 1721 // Initialize plugins (optional). |
| 1801 if (source.HasKey(keys::kPlugins)) { | 1722 if (manifest->HasKey(keys::kPlugins)) { |
| 1802 ListValue* list_value = NULL; | 1723 ListValue* list_value = NULL; |
| 1803 if (!source.GetList(keys::kPlugins, &list_value)) { | 1724 if (!manifest->GetList(keys::kPlugins, &list_value)) { |
| 1804 *error = errors::kInvalidPlugins; | 1725 *error = errors::kInvalidPlugins; |
| 1805 return false; | 1726 return false; |
| 1806 } | 1727 } |
| 1807 | 1728 |
| 1808 for (size_t i = 0; i < list_value->GetSize(); ++i) { | 1729 for (size_t i = 0; i < list_value->GetSize(); ++i) { |
| 1809 DictionaryValue* plugin_value = NULL; | 1730 DictionaryValue* plugin_value = NULL; |
| 1810 std::string path_str; | 1731 std::string path_str; |
| 1811 bool is_public = false; | 1732 bool is_public = false; |
| 1812 | 1733 |
| 1813 if (!list_value->GetDictionary(i, &plugin_value)) { | 1734 if (!list_value->GetDictionary(i, &plugin_value)) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1835 // parse the manifest entry so that error messages are consistently | 1756 // parse the manifest entry so that error messages are consistently |
| 1836 // displayed across platforms. | 1757 // displayed across platforms. |
| 1837 #if !defined(OS_CHROMEOS) | 1758 #if !defined(OS_CHROMEOS) |
| 1838 plugins_.push_back(PluginInfo()); | 1759 plugins_.push_back(PluginInfo()); |
| 1839 plugins_.back().path = path().Append(FilePath::FromUTF8Unsafe(path_str)); | 1760 plugins_.back().path = path().Append(FilePath::FromUTF8Unsafe(path_str)); |
| 1840 plugins_.back().is_public = is_public; | 1761 plugins_.back().is_public = is_public; |
| 1841 #endif | 1762 #endif |
| 1842 } | 1763 } |
| 1843 } | 1764 } |
| 1844 | 1765 |
| 1845 if (source.HasKey(keys::kNaClModules)) { | 1766 if (manifest->HasKey(keys::kNaClModules)) { |
| 1846 ListValue* list_value = NULL; | 1767 ListValue* list_value = NULL; |
| 1847 if (!source.GetList(keys::kNaClModules, &list_value)) { | 1768 if (!manifest->GetList(keys::kNaClModules, &list_value)) { |
| 1848 *error = errors::kInvalidNaClModules; | 1769 *error = errors::kInvalidNaClModules; |
| 1849 return false; | 1770 return false; |
| 1850 } | 1771 } |
| 1851 | 1772 |
| 1852 for (size_t i = 0; i < list_value->GetSize(); ++i) { | 1773 for (size_t i = 0; i < list_value->GetSize(); ++i) { |
| 1853 DictionaryValue* module_value = NULL; | 1774 DictionaryValue* module_value = NULL; |
| 1854 std::string path_str; | 1775 std::string path_str; |
| 1855 std::string mime_type; | 1776 std::string mime_type; |
| 1856 | 1777 |
| 1857 if (!list_value->GetDictionary(i, &module_value)) { | 1778 if (!list_value->GetDictionary(i, &module_value)) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1873 return false; | 1794 return false; |
| 1874 } | 1795 } |
| 1875 | 1796 |
| 1876 nacl_modules_.push_back(NaClModuleInfo()); | 1797 nacl_modules_.push_back(NaClModuleInfo()); |
| 1877 nacl_modules_.back().url = GetResourceURL(path_str); | 1798 nacl_modules_.back().url = GetResourceURL(path_str); |
| 1878 nacl_modules_.back().mime_type = mime_type; | 1799 nacl_modules_.back().mime_type = mime_type; |
| 1879 } | 1800 } |
| 1880 } | 1801 } |
| 1881 | 1802 |
| 1882 // Initialize content scripts (optional). | 1803 // Initialize content scripts (optional). |
| 1883 if (source.HasKey(keys::kContentScripts)) { | 1804 if (manifest->HasKey(keys::kContentScripts)) { |
| 1884 ListValue* list_value; | 1805 ListValue* list_value; |
| 1885 if (!source.GetList(keys::kContentScripts, &list_value)) { | 1806 if (!manifest->GetList(keys::kContentScripts, &list_value)) { |
| 1886 *error = errors::kInvalidContentScriptsList; | 1807 *error = errors::kInvalidContentScriptsList; |
| 1887 return false; | 1808 return false; |
| 1888 } | 1809 } |
| 1889 | 1810 |
| 1890 for (size_t i = 0; i < list_value->GetSize(); ++i) { | 1811 for (size_t i = 0; i < list_value->GetSize(); ++i) { |
| 1891 DictionaryValue* content_script = NULL; | 1812 DictionaryValue* content_script = NULL; |
| 1892 if (!list_value->GetDictionary(i, &content_script)) { | 1813 if (!list_value->GetDictionary(i, &content_script)) { |
| 1893 *error = ExtensionErrorUtils::FormatErrorMessage( | 1814 *error = ExtensionErrorUtils::FormatErrorMessage( |
| 1894 errors::kInvalidContentScript, base::IntToString(i)); | 1815 errors::kInvalidContentScript, base::IntToString(i)); |
| 1895 return false; | 1816 return false; |
| 1896 } | 1817 } |
| 1897 | 1818 |
| 1898 UserScript script; | 1819 UserScript script; |
| 1899 if (!LoadUserScriptHelper(content_script, i, flags, error, &script)) | 1820 if (!LoadUserScriptHelper(content_script, i, flags, error, &script)) |
| 1900 return false; // Failed to parse script context definition. | 1821 return false; // Failed to parse script context definition. |
| 1901 script.set_extension_id(id()); | 1822 script.set_extension_id(id()); |
| 1902 if (converted_from_user_script_) { | 1823 if (converted_from_user_script_) { |
| 1903 script.set_emulate_greasemonkey(true); | 1824 script.set_emulate_greasemonkey(true); |
| 1904 script.set_match_all_frames(true); // Greasemonkey matches all frames. | 1825 script.set_match_all_frames(true); // Greasemonkey matches all frames. |
| 1905 } | 1826 } |
| 1906 content_scripts_.push_back(script); | 1827 content_scripts_.push_back(script); |
| 1907 } | 1828 } |
| 1908 } | 1829 } |
| 1909 | 1830 |
| 1910 // Initialize page action (optional). | 1831 // Initialize page action (optional). |
| 1911 DictionaryValue* page_action_value = NULL; | 1832 DictionaryValue* page_action_value = NULL; |
| 1912 | 1833 |
| 1913 if (source.HasKey(keys::kPageActions)) { | 1834 if (manifest->HasKey(keys::kPageActions)) { |
| 1914 ListValue* list_value = NULL; | 1835 ListValue* list_value = NULL; |
| 1915 if (!source.GetList(keys::kPageActions, &list_value)) { | 1836 if (!manifest->GetList(keys::kPageActions, &list_value)) { |
| 1916 *error = errors::kInvalidPageActionsList; | 1837 *error = errors::kInvalidPageActionsList; |
| 1917 return false; | 1838 return false; |
| 1918 } | 1839 } |
| 1919 | 1840 |
| 1920 size_t list_value_length = list_value->GetSize(); | 1841 size_t list_value_length = list_value->GetSize(); |
| 1921 | 1842 |
| 1922 if (list_value_length == 0u) { | 1843 if (list_value_length == 0u) { |
| 1923 // A list with zero items is allowed, and is equivalent to not having | 1844 // A list with zero items is allowed, and is equivalent to not having |
| 1924 // a page_actions key in the manifest. Don't set |page_action_value|. | 1845 // a page_actions key in the manifest. Don't set |page_action_value|. |
| 1925 } else if (list_value_length == 1u) { | 1846 } else if (list_value_length == 1u) { |
| 1926 if (!list_value->GetDictionary(0, &page_action_value)) { | 1847 if (!list_value->GetDictionary(0, &page_action_value)) { |
| 1927 *error = errors::kInvalidPageAction; | 1848 *error = errors::kInvalidPageAction; |
| 1928 return false; | 1849 return false; |
| 1929 } | 1850 } |
| 1930 } else { // list_value_length > 1u. | 1851 } else { // list_value_length > 1u. |
| 1931 *error = errors::kInvalidPageActionsListSize; | 1852 *error = errors::kInvalidPageActionsListSize; |
| 1932 return false; | 1853 return false; |
| 1933 } | 1854 } |
| 1934 } else if (source.HasKey(keys::kPageAction)) { | 1855 } else if (manifest->HasKey(keys::kPageAction)) { |
| 1935 if (!source.GetDictionary(keys::kPageAction, &page_action_value)) { | 1856 if (!manifest->GetDictionary(keys::kPageAction, &page_action_value)) { |
| 1936 *error = errors::kInvalidPageAction; | 1857 *error = errors::kInvalidPageAction; |
| 1937 return false; | 1858 return false; |
| 1938 } | 1859 } |
| 1939 } | 1860 } |
| 1940 | 1861 |
| 1941 // If page_action_value is not NULL, then there was a valid page action. | 1862 // If page_action_value is not NULL, then there was a valid page action. |
| 1942 if (page_action_value) { | 1863 if (page_action_value) { |
| 1943 page_action_.reset( | 1864 page_action_.reset( |
| 1944 LoadExtensionActionHelper(page_action_value, error)); | 1865 LoadExtensionActionHelper(page_action_value, error)); |
| 1945 if (!page_action_.get()) | 1866 if (!page_action_.get()) |
| 1946 return false; // Failed to parse page action definition. | 1867 return false; // Failed to parse page action definition. |
| 1947 } | 1868 } |
| 1948 | 1869 |
| 1949 // Initialize browser action (optional). | 1870 // Initialize browser action (optional). |
| 1950 if (source.HasKey(keys::kBrowserAction)) { | 1871 if (manifest->HasKey(keys::kBrowserAction)) { |
| 1951 DictionaryValue* browser_action_value = NULL; | 1872 DictionaryValue* browser_action_value = NULL; |
| 1952 if (!source.GetDictionary(keys::kBrowserAction, &browser_action_value)) { | 1873 if (!manifest->GetDictionary(keys::kBrowserAction, &browser_action_value)) { |
| 1953 *error = errors::kInvalidBrowserAction; | 1874 *error = errors::kInvalidBrowserAction; |
| 1954 return false; | 1875 return false; |
| 1955 } | 1876 } |
| 1956 | 1877 |
| 1957 browser_action_.reset( | 1878 browser_action_.reset( |
| 1958 LoadExtensionActionHelper(browser_action_value, error)); | 1879 LoadExtensionActionHelper(browser_action_value, error)); |
| 1959 if (!browser_action_.get()) | 1880 if (!browser_action_.get()) |
| 1960 return false; // Failed to parse browser action definition. | 1881 return false; // Failed to parse browser action definition. |
| 1961 } | 1882 } |
| 1962 | 1883 |
| 1963 // Initialize file browser actions (optional). | 1884 // Initialize file browser actions (optional). |
| 1964 if (source.HasKey(keys::kFileBrowserHandlers)) { | 1885 if (manifest->HasKey(keys::kFileBrowserHandlers)) { |
| 1965 ListValue* file_browser_handlers_value = NULL; | 1886 ListValue* file_browser_handlers_value = NULL; |
| 1966 if (!source.GetList(keys::kFileBrowserHandlers, | 1887 if (!manifest->GetList(keys::kFileBrowserHandlers, |
| 1967 &file_browser_handlers_value)) { | 1888 &file_browser_handlers_value)) { |
| 1968 *error = errors::kInvalidFileBrowserHandler; | 1889 *error = errors::kInvalidFileBrowserHandler; |
| 1969 return false; | 1890 return false; |
| 1970 } | 1891 } |
| 1971 | 1892 |
| 1972 file_browser_handlers_.reset( | 1893 file_browser_handlers_.reset( |
| 1973 LoadFileBrowserHandlers(file_browser_handlers_value, error)); | 1894 LoadFileBrowserHandlers(file_browser_handlers_value, error)); |
| 1974 if (!file_browser_handlers_.get()) | 1895 if (!file_browser_handlers_.get()) |
| 1975 return false; // Failed to parse file browser actions definition. | 1896 return false; // Failed to parse file browser actions definition. |
| 1976 } | 1897 } |
| 1977 | 1898 |
| 1978 // App isolation. | 1899 // App isolation. |
| 1979 if (api_permissions.count(ExtensionAPIPermission::kExperimental)) { | 1900 if (api_permissions.count(ExtensionAPIPermission::kExperimental)) { |
| 1980 if (!LoadAppIsolation(manifest_value_.get(), error)) | 1901 if (is_app() && !LoadAppIsolation(manifest_.get(), error)) |
| 1981 return false; | 1902 return false; |
| 1982 } | 1903 } |
| 1983 | 1904 |
| 1984 // Initialize options page url (optional). | 1905 // Initialize options page url (optional). |
| 1985 // Function LoadIsApp() set is_app_ above. | 1906 if (manifest->HasKey(keys::kOptionsPage)) { |
| 1986 if (source.HasKey(keys::kOptionsPage)) { | |
| 1987 std::string options_str; | 1907 std::string options_str; |
| 1988 if (!source.GetString(keys::kOptionsPage, &options_str)) { | 1908 if (!manifest->GetString(keys::kOptionsPage, &options_str)) { |
| 1989 *error = errors::kInvalidOptionsPage; | 1909 *error = errors::kInvalidOptionsPage; |
| 1990 return false; | 1910 return false; |
| 1991 } | 1911 } |
| 1992 | 1912 |
| 1993 if (is_hosted_app()) { | 1913 if (is_hosted_app()) { |
| 1994 // hosted apps require an absolute URL. | 1914 // hosted apps require an absolute URL. |
| 1995 GURL options_url(options_str); | 1915 GURL options_url(options_str); |
| 1996 if (!options_url.is_valid() || | 1916 if (!options_url.is_valid() || |
| 1997 !(options_url.SchemeIs("http") || options_url.SchemeIs("https"))) { | 1917 !(options_url.SchemeIs("http") || options_url.SchemeIs("https"))) { |
| 1998 *error = errors::kInvalidOptionsPageInHostedApp; | 1918 *error = errors::kInvalidOptionsPageInHostedApp; |
| 1999 return false; | 1919 return false; |
| 2000 } | 1920 } |
| 2001 options_url_ = options_url; | 1921 options_url_ = options_url; |
| 2002 } else { | 1922 } else { |
| 2003 GURL absolute(options_str); | 1923 GURL absolute(options_str); |
| 2004 if (absolute.is_valid()) { | 1924 if (absolute.is_valid()) { |
| 2005 *error = errors::kInvalidOptionsPageExpectUrlInPackage; | 1925 *error = errors::kInvalidOptionsPageExpectUrlInPackage; |
| 2006 return false; | 1926 return false; |
| 2007 } | 1927 } |
| 2008 options_url_ = GetResourceURL(options_str); | 1928 options_url_ = GetResourceURL(options_str); |
| 2009 if (!options_url_.is_valid()) { | 1929 if (!options_url_.is_valid()) { |
| 2010 *error = errors::kInvalidOptionsPage; | 1930 *error = errors::kInvalidOptionsPage; |
| 2011 return false; | 1931 return false; |
| 2012 } | 1932 } |
| 2013 } | 1933 } |
| 2014 } | 1934 } |
| 2015 | 1935 |
| 2016 // Initialize background url (optional). | 1936 // Initialize background url (optional). |
| 2017 if (source.HasKey(keys::kBackground)) { | 1937 if (manifest->HasKey(keys::kBackground)) { |
| 2018 std::string background_str; | 1938 std::string background_str; |
| 2019 if (!source.GetString(keys::kBackground, &background_str)) { | 1939 if (!manifest->GetString(keys::kBackground, &background_str)) { |
| 2020 *error = errors::kInvalidBackground; | 1940 *error = errors::kInvalidBackground; |
| 2021 return false; | 1941 return false; |
| 2022 } | 1942 } |
| 2023 | 1943 |
| 2024 if (is_hosted_app()) { | 1944 if (is_hosted_app()) { |
| 2025 // Make sure "background" permission is set. | 1945 // Make sure "background" permission is set. |
| 2026 if (!api_permissions.count(ExtensionAPIPermission::kBackground)) { | 1946 if (!api_permissions.count(ExtensionAPIPermission::kBackground)) { |
| 2027 *error = errors::kBackgroundPermissionNeeded; | 1947 *error = errors::kBackgroundPermissionNeeded; |
| 2028 return false; | 1948 return false; |
| 2029 } | 1949 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2040 bg_page.SchemeIs("http")))) { | 1960 bg_page.SchemeIs("http")))) { |
| 2041 *error = errors::kInvalidBackgroundInHostedApp; | 1961 *error = errors::kInvalidBackgroundInHostedApp; |
| 2042 return false; | 1962 return false; |
| 2043 } | 1963 } |
| 2044 background_url_ = bg_page; | 1964 background_url_ = bg_page; |
| 2045 } else { | 1965 } else { |
| 2046 background_url_ = GetResourceURL(background_str); | 1966 background_url_ = GetResourceURL(background_str); |
| 2047 } | 1967 } |
| 2048 } | 1968 } |
| 2049 | 1969 |
| 2050 if (source.HasKey(keys::kDefaultLocale)) { | 1970 if (manifest->HasKey(keys::kDefaultLocale)) { |
| 2051 if (!source.GetString(keys::kDefaultLocale, &default_locale_) || | 1971 if (!manifest->GetString(keys::kDefaultLocale, &default_locale_) || |
| 2052 !l10n_util::IsValidLocaleSyntax(default_locale_)) { | 1972 !l10n_util::IsValidLocaleSyntax(default_locale_)) { |
| 2053 *error = errors::kInvalidDefaultLocale; | 1973 *error = errors::kInvalidDefaultLocale; |
| 2054 return false; | 1974 return false; |
| 2055 } | 1975 } |
| 2056 } | 1976 } |
| 2057 | 1977 |
| 2058 // Chrome URL overrides (optional) | 1978 // Chrome URL overrides (optional) |
| 2059 if (source.HasKey(keys::kChromeURLOverrides)) { | 1979 if (manifest->HasKey(keys::kChromeURLOverrides)) { |
| 2060 DictionaryValue* overrides = NULL; | 1980 DictionaryValue* overrides = NULL; |
| 2061 if (!source.GetDictionary(keys::kChromeURLOverrides, &overrides)) { | 1981 if (!manifest->GetDictionary(keys::kChromeURLOverrides, &overrides)) { |
| 2062 *error = errors::kInvalidChromeURLOverrides; | 1982 *error = errors::kInvalidChromeURLOverrides; |
| 2063 return false; | 1983 return false; |
| 2064 } | 1984 } |
| 2065 | 1985 |
| 2066 // Validate that the overrides are all strings | 1986 // Validate that the overrides are all strings |
| 2067 for (DictionaryValue::key_iterator iter = overrides->begin_keys(); | 1987 for (DictionaryValue::key_iterator iter = overrides->begin_keys(); |
| 2068 iter != overrides->end_keys(); ++iter) { | 1988 iter != overrides->end_keys(); ++iter) { |
| 2069 std::string page = *iter; | 1989 std::string page = *iter; |
| 2070 std::string val; | 1990 std::string val; |
| 2071 // 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 Loading... |
| 2093 } | 2013 } |
| 2094 | 2014 |
| 2095 // An extension may override at most one page. | 2015 // An extension may override at most one page. |
| 2096 if (overrides->size() > 1) { | 2016 if (overrides->size() > 1) { |
| 2097 *error = errors::kMultipleOverrides; | 2017 *error = errors::kMultipleOverrides; |
| 2098 return false; | 2018 return false; |
| 2099 } | 2019 } |
| 2100 } | 2020 } |
| 2101 | 2021 |
| 2102 if (api_permissions.count(ExtensionAPIPermission::kExperimental) && | 2022 if (api_permissions.count(ExtensionAPIPermission::kExperimental) && |
| 2103 source.HasKey(keys::kInputComponents)) { | 2023 manifest->HasKey(keys::kInputComponents)) { |
| 2104 ListValue* list_value = NULL; | 2024 ListValue* list_value = NULL; |
| 2105 if (!source.GetList(keys::kInputComponents, &list_value)) { | 2025 if (!manifest->GetList(keys::kInputComponents, &list_value)) { |
| 2106 *error = errors::kInvalidInputComponents; | 2026 *error = errors::kInvalidInputComponents; |
| 2107 return false; | 2027 return false; |
| 2108 } | 2028 } |
| 2109 | 2029 |
| 2110 for (size_t i = 0; i < list_value->GetSize(); ++i) { | 2030 for (size_t i = 0; i < list_value->GetSize(); ++i) { |
| 2111 DictionaryValue* module_value = NULL; | 2031 DictionaryValue* module_value = NULL; |
| 2112 std::string name_str; | 2032 std::string name_str; |
| 2113 InputComponentType type; | 2033 InputComponentType type; |
| 2114 std::string id_str; | 2034 std::string id_str; |
| 2115 std::string description_str; | 2035 std::string description_str; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2224 input_components_.back().description = description_str; | 2144 input_components_.back().description = description_str; |
| 2225 input_components_.back().language = language_str; | 2145 input_components_.back().language = language_str; |
| 2226 input_components_.back().layouts.insert(layouts.begin(), layouts.end()); | 2146 input_components_.back().layouts.insert(layouts.begin(), layouts.end()); |
| 2227 input_components_.back().shortcut_keycode = shortcut_keycode_str; | 2147 input_components_.back().shortcut_keycode = shortcut_keycode_str; |
| 2228 input_components_.back().shortcut_alt = shortcut_alt; | 2148 input_components_.back().shortcut_alt = shortcut_alt; |
| 2229 input_components_.back().shortcut_ctrl = shortcut_ctrl; | 2149 input_components_.back().shortcut_ctrl = shortcut_ctrl; |
| 2230 input_components_.back().shortcut_shift = shortcut_shift; | 2150 input_components_.back().shortcut_shift = shortcut_shift; |
| 2231 } | 2151 } |
| 2232 } | 2152 } |
| 2233 | 2153 |
| 2234 if (source.HasKey(keys::kOmnibox)) { | 2154 if (manifest->HasKey(keys::kOmnibox)) { |
| 2235 if (!source.GetString(keys::kOmniboxKeyword, &omnibox_keyword_) || | 2155 if (!manifest->GetString(keys::kOmniboxKeyword, &omnibox_keyword_) || |
| 2236 omnibox_keyword_.empty()) { | 2156 omnibox_keyword_.empty()) { |
| 2237 *error = errors::kInvalidOmniboxKeyword; | 2157 *error = errors::kInvalidOmniboxKeyword; |
| 2238 return false; | 2158 return false; |
| 2239 } | 2159 } |
| 2240 } | 2160 } |
| 2241 | 2161 |
| 2242 if (source.HasKey(keys::kContentSecurityPolicy)) { | 2162 if (manifest->HasKey(keys::kContentSecurityPolicy)) { |
| 2243 std::string content_security_policy; | 2163 std::string content_security_policy; |
| 2244 if (!source.GetString(keys::kContentSecurityPolicy, | 2164 if (!manifest->GetString(keys::kContentSecurityPolicy, |
| 2245 &content_security_policy)) { | 2165 &content_security_policy)) { |
| 2246 *error = errors::kInvalidContentSecurityPolicy; | 2166 *error = errors::kInvalidContentSecurityPolicy; |
| 2247 return false; | 2167 return false; |
| 2248 } | 2168 } |
| 2249 if (!ContentSecurityPolicyIsLegal(content_security_policy)) { | 2169 if (!ContentSecurityPolicyIsLegal(content_security_policy)) { |
| 2250 *error = errors::kInvalidContentSecurityPolicy; | 2170 *error = errors::kInvalidContentSecurityPolicy; |
| 2251 return false; | 2171 return false; |
| 2252 } | 2172 } |
| 2253 if (manifest_version_ >= 2 && | 2173 if (manifest_version_ >= 2 && |
| 2254 !ContentSecurityPolicyIsSecure(content_security_policy)) { | 2174 !ContentSecurityPolicyIsSecure(content_security_policy)) { |
| 2255 *error = errors::kInvalidContentSecurityPolicy; | 2175 *error = errors::kInvalidContentSecurityPolicy; |
| 2256 return false; | 2176 return false; |
| 2257 } | 2177 } |
| 2258 | 2178 |
| 2259 content_security_policy_ = content_security_policy; | 2179 content_security_policy_ = content_security_policy; |
| 2260 } else if (manifest_version_ >= 2) { | 2180 } else if (manifest_version_ >= 2) { |
| 2261 // Manifest version 2 introduced a default Content-Security-Policy. | 2181 // Manifest version 2 introduced a default Content-Security-Policy. |
| 2262 // TODO(abarth): Should we continue to let extensions override the | 2182 // TODO(abarth): Should we continue to let extensions override the |
| 2263 // default Content-Security-Policy? | 2183 // default Content-Security-Policy? |
| 2264 content_security_policy_ = kDefaultContentSecurityPolicy; | 2184 content_security_policy_ = kDefaultContentSecurityPolicy; |
| 2265 CHECK(ContentSecurityPolicyIsSecure(content_security_policy_)); | 2185 CHECK(ContentSecurityPolicyIsSecure(content_security_policy_)); |
| 2266 } | 2186 } |
| 2267 | 2187 |
| 2268 // Initialize devtools page url (optional). | 2188 // Initialize devtools page url (optional). |
| 2269 if (source.HasKey(keys::kDevToolsPage)) { | 2189 if (manifest->HasKey(keys::kDevToolsPage)) { |
| 2270 std::string devtools_str; | 2190 std::string devtools_str; |
| 2271 if (!source.GetString(keys::kDevToolsPage, &devtools_str)) { | 2191 if (!manifest->GetString(keys::kDevToolsPage, &devtools_str)) { |
| 2272 *error = errors::kInvalidDevToolsPage; | 2192 *error = errors::kInvalidDevToolsPage; |
| 2273 return false; | 2193 return false; |
| 2274 } | 2194 } |
| 2275 if (!api_permissions.count(ExtensionAPIPermission::kExperimental)) { | 2195 if (!api_permissions.count(ExtensionAPIPermission::kExperimental)) { |
| 2276 *error = errors::kDevToolsExperimental; | 2196 *error = errors::kDevToolsExperimental; |
| 2277 return false; | 2197 return false; |
| 2278 } | 2198 } |
| 2279 devtools_url_ = GetResourceURL(devtools_str); | 2199 devtools_url_ = GetResourceURL(devtools_str); |
| 2280 } | 2200 } |
| 2281 | 2201 |
| 2282 // Initialize sidebar action (optional). | 2202 // Initialize sidebar action (optional). |
| 2283 if (source.HasKey(keys::kSidebar)) { | 2203 if (manifest->HasKey(keys::kSidebar)) { |
| 2284 DictionaryValue* sidebar_value = NULL; | 2204 DictionaryValue* sidebar_value = NULL; |
| 2285 if (!source.GetDictionary(keys::kSidebar, &sidebar_value)) { | 2205 if (!manifest->GetDictionary(keys::kSidebar, &sidebar_value)) { |
| 2286 *error = errors::kInvalidSidebar; | 2206 *error = errors::kInvalidSidebar; |
| 2287 return false; | 2207 return false; |
| 2288 } | 2208 } |
| 2289 if (!api_permissions.count(ExtensionAPIPermission::kExperimental)) { | 2209 if (!api_permissions.count(ExtensionAPIPermission::kExperimental)) { |
| 2290 *error = errors::kSidebarExperimental; | 2210 *error = errors::kSidebarExperimental; |
| 2291 return false; | 2211 return false; |
| 2292 } | 2212 } |
| 2293 sidebar_defaults_.reset(LoadExtensionSidebarDefaults(sidebar_value, error)); | 2213 sidebar_defaults_.reset(LoadExtensionSidebarDefaults(sidebar_value, error)); |
| 2294 if (!sidebar_defaults_.get()) | 2214 if (!sidebar_defaults_.get()) |
| 2295 return false; // Failed to parse sidebar definition. | 2215 return false; // Failed to parse sidebar definition. |
| 2296 } | 2216 } |
| 2297 | 2217 |
| 2298 // Initialize text-to-speech voices (optional). | 2218 // Initialize text-to-speech voices (optional). |
| 2299 if (source.HasKey(keys::kTtsEngine)) { | 2219 if (manifest->HasKey(keys::kTtsEngine)) { |
| 2300 DictionaryValue* tts_dict = NULL; | 2220 DictionaryValue* tts_dict = NULL; |
| 2301 if (!source.GetDictionary(keys::kTtsEngine, &tts_dict)) { | 2221 if (!manifest->GetDictionary(keys::kTtsEngine, &tts_dict)) { |
| 2302 *error = errors::kInvalidTts; | 2222 *error = errors::kInvalidTts; |
| 2303 return false; | 2223 return false; |
| 2304 } | 2224 } |
| 2305 | 2225 |
| 2306 if (tts_dict->HasKey(keys::kTtsVoices)) { | 2226 if (tts_dict->HasKey(keys::kTtsVoices)) { |
| 2307 ListValue* tts_voices = NULL; | 2227 ListValue* tts_voices = NULL; |
| 2308 if (!tts_dict->GetList(keys::kTtsVoices, &tts_voices)) { | 2228 if (!tts_dict->GetList(keys::kTtsVoices, &tts_voices)) { |
| 2309 *error = errors::kInvalidTtsVoices; | 2229 *error = errors::kInvalidTtsVoices; |
| 2310 return false; | 2230 return false; |
| 2311 } | 2231 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2372 voice_data.event_types.insert(event_type); | 2292 voice_data.event_types.insert(event_type); |
| 2373 } | 2293 } |
| 2374 } | 2294 } |
| 2375 | 2295 |
| 2376 tts_voices_.push_back(voice_data); | 2296 tts_voices_.push_back(voice_data); |
| 2377 } | 2297 } |
| 2378 } | 2298 } |
| 2379 } | 2299 } |
| 2380 | 2300 |
| 2381 // Initialize web intents (optional). | 2301 // Initialize web intents (optional). |
| 2382 if (!LoadWebIntentServices(source, error)) | 2302 if (!LoadWebIntentServices(manifest, error)) |
| 2383 return false; | 2303 return false; |
| 2384 | 2304 |
| 2385 // Initialize incognito behavior. Apps default to split mode, extensions | 2305 // Initialize incognito behavior. Apps default to split mode, extensions |
| 2386 // default to spanning. | 2306 // default to spanning. |
| 2387 incognito_split_mode_ = is_app(); | 2307 incognito_split_mode_ = is_app(); |
| 2388 if (source.HasKey(keys::kIncognito)) { | 2308 if (manifest->HasKey(keys::kIncognito)) { |
| 2389 std::string value; | 2309 std::string value; |
| 2390 if (!source.GetString(keys::kIncognito, &value)) { | 2310 if (!manifest->GetString(keys::kIncognito, &value)) { |
| 2391 *error = errors::kInvalidIncognitoBehavior; | 2311 *error = errors::kInvalidIncognitoBehavior; |
| 2392 return false; | 2312 return false; |
| 2393 } | 2313 } |
| 2394 if (value == values::kIncognitoSpanning) { | 2314 if (value == values::kIncognitoSpanning) { |
| 2395 incognito_split_mode_ = false; | 2315 incognito_split_mode_ = false; |
| 2396 } else if (value == values::kIncognitoSplit) { | 2316 } else if (value == values::kIncognitoSplit) { |
| 2397 incognito_split_mode_ = true; | 2317 incognito_split_mode_ = true; |
| 2398 } else { | 2318 } else { |
| 2399 *error = errors::kInvalidIncognitoBehavior; | 2319 *error = errors::kInvalidIncognitoBehavior; |
| 2400 return false; | 2320 return false; |
| 2401 } | 2321 } |
| 2402 } | 2322 } |
| 2403 | 2323 |
| 2404 // Initialize offline-enabled status. Defaults to false. | 2324 // Initialize offline-enabled status. Defaults to false. |
| 2405 if (source.HasKey(keys::kOfflineEnabled)) { | 2325 if (manifest->HasKey(keys::kOfflineEnabled)) { |
| 2406 if (!source.GetBoolean(keys::kOfflineEnabled, &offline_enabled_)) { | 2326 if (!manifest->GetBoolean(keys::kOfflineEnabled, &offline_enabled_)) { |
| 2407 *error = errors::kInvalidOfflineEnabled; | 2327 *error = errors::kInvalidOfflineEnabled; |
| 2408 return false; | 2328 return false; |
| 2409 } | 2329 } |
| 2410 } | 2330 } |
| 2411 | 2331 |
| 2412 // Initialize requirements (optional). Not actually persisted (they're only | 2332 // Initialize requirements (optional). Not actually persisted (they're only |
| 2413 // used by the store), but still validated. | 2333 // used by the store), but still validated. |
| 2414 if (source.HasKey(keys::kRequirements)) { | 2334 if (manifest->HasKey(keys::kRequirements)) { |
| 2415 DictionaryValue* requirements_value = NULL; | 2335 DictionaryValue* requirements_value = NULL; |
| 2416 if (!source.GetDictionary(keys::kRequirements, &requirements_value)) { | 2336 if (!manifest->GetDictionary(keys::kRequirements, &requirements_value)) { |
| 2417 *error = errors::kInvalidRequirements; | 2337 *error = errors::kInvalidRequirements; |
| 2418 return false; | 2338 return false; |
| 2419 } | 2339 } |
| 2420 | 2340 |
| 2421 for (DictionaryValue::key_iterator it = requirements_value->begin_keys(); | 2341 for (DictionaryValue::key_iterator it = requirements_value->begin_keys(); |
| 2422 it != requirements_value->end_keys(); ++it) { | 2342 it != requirements_value->end_keys(); ++it) { |
| 2423 DictionaryValue* requirement_value; | 2343 DictionaryValue* requirement_value; |
| 2424 if (!requirements_value->GetDictionaryWithoutPathExpansion( | 2344 if (!requirements_value->GetDictionaryWithoutPathExpansion( |
| 2425 *it, &requirement_value)) { | 2345 *it, &requirement_value)) { |
| 2426 *error = ExtensionErrorUtils::FormatErrorMessage( | 2346 *error = ExtensionErrorUtils::FormatErrorMessage( |
| 2427 errors::kInvalidRequirement, *it); | 2347 errors::kInvalidRequirement, *it); |
| 2428 return false; | 2348 return false; |
| 2429 } | 2349 } |
| 2430 } | 2350 } |
| 2431 } | 2351 } |
| 2432 | 2352 |
| 2433 if (HasMultipleUISurfaces()) { | 2353 if (HasMultipleUISurfaces()) { |
| 2434 *error = errors::kOneUISurfaceOnly; | 2354 *error = errors::kOneUISurfaceOnly; |
| 2435 return false; | 2355 return false; |
| 2436 } | 2356 } |
| 2437 | 2357 |
| 2438 runtime_data_.SetActivePermissions(new ExtensionPermissionSet( | 2358 runtime_data_.SetActivePermissions(new ExtensionPermissionSet( |
| 2439 this, api_permissions, host_permissions)); | 2359 this, api_permissions, host_permissions)); |
| 2440 required_permission_set_ = new ExtensionPermissionSet( | 2360 required_permission_set_ = new ExtensionPermissionSet( |
| 2441 this, api_permissions, host_permissions); | 2361 this, api_permissions, host_permissions); |
| 2442 optional_permission_set_ = new ExtensionPermissionSet( | 2362 optional_permission_set_ = new ExtensionPermissionSet( |
| 2443 optional_api_permissions, optional_host_permissions, URLPatternSet()); | 2363 optional_api_permissions, optional_host_permissions, URLPatternSet()); |
| 2444 | 2364 |
| 2445 // Although |source| is passed in as a const, it's still possible to modify | |
| 2446 // it. This is dangerous since the utility process re-uses |source| after | |
| 2447 // it calls InitFromValue, passing it up to the browser process which calls | |
| 2448 // InitFromValue again. As a result, we need to make sure that nobody | |
| 2449 // accidentally modifies it. | |
| 2450 DCHECK(source.Equals(manifest_value_.get())); | |
| 2451 | |
| 2452 return true; | 2365 return true; |
| 2453 } | 2366 } |
| 2454 | 2367 |
| 2455 GURL Extension::GetHomepageURL() const { | 2368 GURL Extension::GetHomepageURL() const { |
| 2456 if (homepage_url_.is_valid()) | 2369 if (homepage_url_.is_valid()) |
| 2457 return homepage_url_; | 2370 return homepage_url_; |
| 2458 | 2371 |
| 2459 if (!UpdatesFromGallery()) | 2372 if (!UpdatesFromGallery()) |
| 2460 return GURL(); | 2373 return GURL(); |
| 2461 | 2374 |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2597 | 2510 |
| 2598 GURL Extension::GetIconURL(int size, | 2511 GURL Extension::GetIconURL(int size, |
| 2599 ExtensionIconSet::MatchType match_type) const { | 2512 ExtensionIconSet::MatchType match_type) const { |
| 2600 std::string path = icons().Get(size, match_type); | 2513 std::string path = icons().Get(size, match_type); |
| 2601 if (path.empty()) | 2514 if (path.empty()) |
| 2602 return GURL(); | 2515 return GURL(); |
| 2603 else | 2516 else |
| 2604 return GetResourceURL(path); | 2517 return GetResourceURL(path); |
| 2605 } | 2518 } |
| 2606 | 2519 |
| 2607 bool Extension::ParsePermissions(const DictionaryValue* source, | 2520 bool Extension::ParsePermissions(const extensions::Manifest* source, |
| 2608 const char* key, | 2521 const char* key, |
| 2609 int flags, | 2522 int flags, |
| 2610 std::string* error, | 2523 std::string* error, |
| 2611 ExtensionAPIPermissionSet* api_permissions, | 2524 ExtensionAPIPermissionSet* api_permissions, |
| 2612 URLPatternSet* host_permissions) { | 2525 URLPatternSet* host_permissions) { |
| 2613 if (source->HasKey(key)) { | 2526 if (source->HasKey(key)) { |
| 2614 // When strict error checks are enabled, make URL pattern parsing strict. | 2527 // When strict error checks are enabled, make URL pattern parsing strict. |
| 2615 URLPattern::ParseOption parse_strictness = | 2528 URLPattern::ParseOption parse_strictness = |
| 2616 (flags & STRICT_ERROR_CHECKS ? URLPattern::ERROR_ON_PORTS | 2529 (flags & STRICT_ERROR_CHECKS ? URLPattern::ERROR_ON_PORTS |
| 2617 : URLPattern::IGNORE_PORTS); | 2530 : URLPattern::IGNORE_PORTS); |
| (...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3087 already_disabled(false), | 3000 already_disabled(false), |
| 3088 extension(extension) {} | 3001 extension(extension) {} |
| 3089 | 3002 |
| 3090 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( | 3003 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( |
| 3091 const Extension* extension, | 3004 const Extension* extension, |
| 3092 const ExtensionPermissionSet* permissions, | 3005 const ExtensionPermissionSet* permissions, |
| 3093 Reason reason) | 3006 Reason reason) |
| 3094 : reason(reason), | 3007 : reason(reason), |
| 3095 extension(extension), | 3008 extension(extension), |
| 3096 permissions(permissions) {} | 3009 permissions(permissions) {} |
| OLD | NEW |