| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/browser/extensions/extension_file_util.h" | 5 #include "chrome/browser/extensions/extension_file_util.h" |
| 6 | 6 |
| 7 #include "app/l10n_util.h" |
| 7 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 8 #include "base/logging.h" | 9 #include "base/logging.h" |
| 9 #include "base/scoped_temp_dir.h" | 10 #include "base/scoped_temp_dir.h" |
| 10 #include "base/string_util.h" | 11 #include "base/string_util.h" |
| 11 #include "chrome/browser/extensions/extension_prefs.h" | 12 #include "chrome/browser/extensions/extension_prefs.h" |
| 12 #include "chrome/browser/extensions/extension_l10n_util.h" | 13 #include "chrome/browser/extensions/extension_l10n_util.h" |
| 13 #include "chrome/common/extensions/extension.h" | 14 #include "chrome/common/extensions/extension.h" |
| 14 #include "chrome/common/extensions/extension_constants.h" | 15 #include "chrome/common/extensions/extension_constants.h" |
| 15 #include "chrome/common/json_value_serializer.h" | 16 #include "chrome/common/json_value_serializer.h" |
| 16 #include "net/base/file_stream.h" | 17 #include "net/base/file_stream.h" |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 | 88 |
| 88 if (!MoveDirSafely(src_dir, version_dir)) { | 89 if (!MoveDirSafely(src_dir, version_dir)) { |
| 89 *error = "Could not move extension directory into profile."; | 90 *error = "Could not move extension directory into profile."; |
| 90 return false; | 91 return false; |
| 91 } | 92 } |
| 92 | 93 |
| 93 scoped_version_dir.Take(); | 94 scoped_version_dir.Take(); |
| 94 return true; | 95 return true; |
| 95 } | 96 } |
| 96 | 97 |
| 97 Extension* LoadExtension(const FilePath& extension_path, bool require_key, | 98 Extension* LoadExtension(const FilePath& extension_path, |
| 99 bool require_key, |
| 98 std::string* error) { | 100 std::string* error) { |
| 99 FilePath manifest_path = | 101 FilePath manifest_path = |
| 100 extension_path.AppendASCII(Extension::kManifestFilename); | 102 extension_path.AppendASCII(Extension::kManifestFilename); |
| 101 if (!file_util::PathExists(manifest_path)) { | 103 if (!file_util::PathExists(manifest_path)) { |
| 102 *error = extension_manifest_errors::kInvalidManifest; | 104 *error = extension_manifest_errors::kInvalidManifest; |
| 103 return NULL; | 105 return NULL; |
| 104 } | 106 } |
| 105 | 107 |
| 106 JSONFileValueSerializer serializer(manifest_path); | 108 JSONFileValueSerializer serializer(manifest_path); |
| 107 scoped_ptr<Value> root(serializer.Deserialize(error)); | 109 scoped_ptr<Value> root(serializer.Deserialize(error)); |
| 108 if (!root.get()) | 110 if (!root.get()) |
| 109 return NULL; | 111 return NULL; |
| 110 | 112 |
| 111 if (!root->IsType(Value::TYPE_DICTIONARY)) { | 113 if (!root->IsType(Value::TYPE_DICTIONARY)) { |
| 112 *error = extension_manifest_errors::kInvalidManifest; | 114 *error = extension_manifest_errors::kInvalidManifest; |
| 113 return NULL; | 115 return NULL; |
| 114 } | 116 } |
| 115 | 117 |
| 118 DictionaryValue* manifest = static_cast<DictionaryValue*>(root.get()); |
| 119 ExtensionMessageBundle* message_bundle = |
| 120 LoadLocaleInfo(extension_path, *manifest, error); |
| 121 if (!message_bundle && !error->empty()) |
| 122 return NULL; |
| 123 |
| 116 scoped_ptr<Extension> extension(new Extension(extension_path)); | 124 scoped_ptr<Extension> extension(new Extension(extension_path)); |
| 117 if (!extension->InitFromValue(*static_cast<DictionaryValue*>(root.get()), | 125 // Assign message bundle to extension. |
| 118 require_key, error)) | 126 extension->set_message_bundle(message_bundle); |
| 127 if (!extension->InitFromValue(*manifest, require_key, error)) |
| 119 return NULL; | 128 return NULL; |
| 120 | 129 |
| 121 if (!ValidateExtension(extension.get(), error)) | 130 if (!ValidateExtension(extension.get(), error)) |
| 122 return NULL; | 131 return NULL; |
| 123 | 132 |
| 124 return extension.release(); | 133 return extension.release(); |
| 125 } | 134 } |
| 126 | 135 |
| 127 bool ValidateExtension(Extension* extension, std::string* error) { | 136 bool ValidateExtension(Extension* extension, std::string* error) { |
| 128 // Validate icons exist. | 137 // Validate icons exist. |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 for (std::vector<std::string>::const_iterator iter = icon_paths.begin(); | 220 for (std::vector<std::string>::const_iterator iter = icon_paths.begin(); |
| 212 iter != icon_paths.end(); ++iter) { | 221 iter != icon_paths.end(); ++iter) { |
| 213 if (!file_util::PathExists(extension->GetResourcePath(*iter))) { | 222 if (!file_util::PathExists(extension->GetResourcePath(*iter))) { |
| 214 *error = StringPrintf("Could not load icon '%s' for page action.", | 223 *error = StringPrintf("Could not load icon '%s' for page action.", |
| 215 iter->c_str()); | 224 iter->c_str()); |
| 216 return false; | 225 return false; |
| 217 } | 226 } |
| 218 } | 227 } |
| 219 } | 228 } |
| 220 | 229 |
| 221 // Load locale information if available. | |
| 222 FilePath locale_path = | |
| 223 extension->path().AppendASCII(Extension::kLocaleFolder); | |
| 224 if (file_util::PathExists(locale_path)) { | |
| 225 if (!extension_l10n_util::AddValidLocales(locale_path, | |
| 226 extension, | |
| 227 error)) { | |
| 228 return false; | |
| 229 } | |
| 230 | |
| 231 if (!extension_l10n_util::ValidateDefaultLocale(extension)) { | |
| 232 *error = extension_manifest_errors::kLocalesNoDefaultLocaleSpecified; | |
| 233 return false; | |
| 234 } | |
| 235 } | |
| 236 | |
| 237 // Check children of extension root to see if any of them start with _ and is | 230 // Check children of extension root to see if any of them start with _ and is |
| 238 // not on the reserved list. | 231 // not on the reserved list. |
| 239 if (!CheckForIllegalFilenames(extension->path(), error)) { | 232 if (!CheckForIllegalFilenames(extension->path(), error)) { |
| 240 return false; | 233 return false; |
| 241 } | 234 } |
| 242 | 235 |
| 243 return true; | 236 return true; |
| 244 } | 237 } |
| 245 | 238 |
| 246 void UninstallExtension(const std::string& id, const FilePath& extensions_dir) { | 239 void UninstallExtension(const std::string& id, const FilePath& extensions_dir) { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 LOG(WARNING) << "Invalid extension ID encountered in extensions " | 297 LOG(WARNING) << "Invalid extension ID encountered in extensions " |
| 305 "directory: " << extension_id; | 298 "directory: " << extension_id; |
| 306 LOG(INFO) << "Deleting invalid extension directory " | 299 LOG(INFO) << "Deleting invalid extension directory " |
| 307 << WideToASCII(extension_path.ToWStringHack()) << "."; | 300 << WideToASCII(extension_path.ToWStringHack()) << "."; |
| 308 file_util::Delete(extension_path, true); // Recursive. | 301 file_util::Delete(extension_path, true); // Recursive. |
| 309 continue; | 302 continue; |
| 310 } | 303 } |
| 311 } | 304 } |
| 312 } | 305 } |
| 313 | 306 |
| 307 ExtensionMessageBundle* LoadLocaleInfo(const FilePath& extension_path, |
| 308 const DictionaryValue& manifest, |
| 309 std::string* error) { |
| 310 error->clear(); |
| 311 // Load locale information if available. |
| 312 FilePath locale_path = extension_path.AppendASCII(Extension::kLocaleFolder); |
| 313 if (!file_util::PathExists(locale_path)) |
| 314 return NULL; |
| 315 |
| 316 std::set<std::string> locales; |
| 317 if (!extension_l10n_util::GetValidLocales(locale_path, &locales, error)) |
| 318 return NULL; |
| 319 |
| 320 std::string default_locale = |
| 321 extension_l10n_util::GetDefaultLocaleFromManifest(manifest, error); |
| 322 if (default_locale.empty() || |
| 323 locales.find(default_locale) == locales.end()) { |
| 324 *error = extension_manifest_errors::kLocalesNoDefaultLocaleSpecified; |
| 325 return NULL; |
| 326 } |
| 327 |
| 328 // We can't call g_browser_process->GetApplicationLocale() since we are not |
| 329 // on the main thread. |
| 330 static std::string app_locale = l10n_util::GetApplicationLocale(L""); |
| 331 if (locales.find(app_locale) == locales.end()) |
| 332 app_locale = ""; |
| 333 ExtensionMessageBundle* message_bundle = |
| 334 extension_l10n_util::LoadMessageCatalogs(locale_path, |
| 335 default_locale, |
| 336 app_locale, |
| 337 error); |
| 338 return message_bundle; |
| 339 } |
| 340 |
| 314 bool CheckForIllegalFilenames(const FilePath& extension_path, | 341 bool CheckForIllegalFilenames(const FilePath& extension_path, |
| 315 std::string* error) { | 342 std::string* error) { |
| 316 // Reserved underscore names. | 343 // Reserved underscore names. |
| 317 static const char* reserved_names[] = { | 344 static const char* reserved_names[] = { |
| 318 Extension::kLocaleFolder | 345 Extension::kLocaleFolder |
| 319 }; | 346 }; |
| 320 static std::set<std::string> reserved_underscore_names( | 347 static std::set<std::string> reserved_underscore_names( |
| 321 reserved_names, reserved_names + arraysize(reserved_names)); | 348 reserved_names, reserved_names + arraysize(reserved_names)); |
| 322 | 349 |
| 323 // Enumerate all files and directories in the extension root. | 350 // Enumerate all files and directories in the extension root. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 343 "Filenames starting with \"_\" are reserved for use by the system", | 370 "Filenames starting with \"_\" are reserved for use by the system", |
| 344 filename.c_str()); | 371 filename.c_str()); |
| 345 return false; | 372 return false; |
| 346 } | 373 } |
| 347 } | 374 } |
| 348 | 375 |
| 349 return true; | 376 return true; |
| 350 } | 377 } |
| 351 | 378 |
| 352 } // extension_file_util | 379 } // extension_file_util |
| OLD | NEW |