| 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 "app/l10n_util.h" |
| 8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/scoped_temp_dir.h" | 10 #include "base/scoped_temp_dir.h" |
| 11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
| 12 #include "chrome/browser/extensions/extension_prefs.h" | 12 #include "chrome/browser/extensions/extension_prefs.h" |
| 13 #include "chrome/common/extensions/extension.h" | 13 #include "chrome/common/extensions/extension.h" |
| 14 #include "chrome/common/extensions/extension_l10n_util.h" | 14 #include "chrome/common/extensions/extension_l10n_util.h" |
| 15 #include "chrome/common/extensions/extension_constants.h" | 15 #include "chrome/common/extensions/extension_constants.h" |
| 16 #include "chrome/common/json_value_serializer.h" | 16 #include "chrome/common/json_value_serializer.h" |
| 17 #include "net/base/file_stream.h" | 17 #include "net/base/file_stream.h" |
| 18 | 18 |
| 19 namespace errors = extension_manifest_errors; |
| 20 |
| 19 namespace extension_file_util { | 21 namespace extension_file_util { |
| 20 | 22 |
| 21 const char kInstallDirectoryName[] = "Extensions"; | 23 const char kInstallDirectoryName[] = "Extensions"; |
| 22 // TODO(mpcomplete): obsolete. remove after migration period. | 24 // TODO(mpcomplete): obsolete. remove after migration period. |
| 23 // http://code.google.com/p/chromium/issues/detail?id=19733 | 25 // http://code.google.com/p/chromium/issues/detail?id=19733 |
| 24 const char kCurrentVersionFileName[] = "Current Version"; | 26 const char kCurrentVersionFileName[] = "Current Version"; |
| 25 | 27 |
| 26 bool MoveDirSafely(const FilePath& source_dir, const FilePath& dest_dir) { | 28 bool MoveDirSafely(const FilePath& source_dir, const FilePath& dest_dir) { |
| 27 if (file_util::PathExists(dest_dir)) { | 29 if (file_util::PathExists(dest_dir)) { |
| 28 if (!file_util::Delete(dest_dir, true)) | 30 if (!file_util::Delete(dest_dir, true)) |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 if (!extension->background_url().is_empty()) { | 265 if (!extension->background_url().is_empty()) { |
| 264 const std::string page_path = extension->background_url().path(); | 266 const std::string page_path = extension->background_url().path(); |
| 265 const FilePath path = extension->GetResource(page_path).GetFilePath(); | 267 const FilePath path = extension->GetResource(page_path).GetFilePath(); |
| 266 if (!file_util::PathExists(path)) { | 268 if (!file_util::PathExists(path)) { |
| 267 *error = StringPrintf("Could not load background page '%s'.", | 269 *error = StringPrintf("Could not load background page '%s'.", |
| 268 WideToUTF8(path.ToWStringHack()).c_str()); | 270 WideToUTF8(path.ToWStringHack()).c_str()); |
| 269 return false; | 271 return false; |
| 270 } | 272 } |
| 271 } | 273 } |
| 272 | 274 |
| 275 // Validate locale info. |
| 276 if (!ValidateLocaleInfo(*extension, error)) |
| 277 return false; |
| 278 |
| 273 // Check children of extension root to see if any of them start with _ and is | 279 // Check children of extension root to see if any of them start with _ and is |
| 274 // not on the reserved list. | 280 // not on the reserved list. |
| 275 if (!CheckForIllegalFilenames(extension->path(), error)) { | 281 if (!CheckForIllegalFilenames(extension->path(), error)) { |
| 276 return false; | 282 return false; |
| 277 } | 283 } |
| 278 | 284 |
| 279 return true; | 285 return true; |
| 280 } | 286 } |
| 281 | 287 |
| 282 void UninstallExtension(const std::string& id, const FilePath& extensions_dir) { | 288 void UninstallExtension(const std::string& id, const FilePath& extensions_dir) { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 app_locale = ""; | 381 app_locale = ""; |
| 376 ExtensionMessageBundle* message_bundle = | 382 ExtensionMessageBundle* message_bundle = |
| 377 extension_l10n_util::LoadMessageCatalogs(locale_path, | 383 extension_l10n_util::LoadMessageCatalogs(locale_path, |
| 378 default_locale, | 384 default_locale, |
| 379 app_locale, | 385 app_locale, |
| 380 locales, | 386 locales, |
| 381 error); | 387 error); |
| 382 return message_bundle; | 388 return message_bundle; |
| 383 } | 389 } |
| 384 | 390 |
| 391 bool ValidateLocaleInfo(const Extension& extension, std::string* error) { |
| 392 // default_locale and _locales have to be both present or both missing. |
| 393 const FilePath path = extension.path().AppendASCII(Extension::kLocaleFolder); |
| 394 bool path_exists = file_util::PathExists(path); |
| 395 std::string default_locale = extension.default_locale(); |
| 396 |
| 397 // If both default locale and _locales folder are empty, skip verification. |
| 398 if (!default_locale.empty() || path_exists) { |
| 399 if (default_locale.empty() && path_exists) { |
| 400 *error = errors::kLocalesNoDefaultLocaleSpecified; |
| 401 return false; |
| 402 } else if (!default_locale.empty() && !path_exists) { |
| 403 *error = errors::kLocalesTreeMissing; |
| 404 return false; |
| 405 } |
| 406 |
| 407 // Treat all folders under _locales as valid locales. |
| 408 file_util::FileEnumerator locales(path, |
| 409 false, |
| 410 file_util::FileEnumerator::DIRECTORIES); |
| 411 |
| 412 FilePath locale_path = locales.Next(); |
| 413 if (locale_path.empty()) { |
| 414 *error = errors::kLocalesTreeMissing; |
| 415 return false; |
| 416 } |
| 417 |
| 418 const FilePath default_locale_path = path.AppendASCII(default_locale); |
| 419 bool has_default_locale_message_file = false; |
| 420 do { |
| 421 // Skip any strings with '.'. This happens sometimes, for example with |
| 422 // '.svn' directories. |
| 423 FilePath relative_path; |
| 424 if (!extension.path().AppendRelativePath(locale_path, &relative_path)) |
| 425 NOTREACHED(); |
| 426 std::wstring subdir(relative_path.ToWStringHack()); |
| 427 if (std::find(subdir.begin(), subdir.end(), L'.') != subdir.end()) |
| 428 continue; |
| 429 |
| 430 FilePath messages_path = |
| 431 locale_path.AppendASCII(Extension::kMessagesFilename); |
| 432 |
| 433 if (!file_util::PathExists(messages_path)) { |
| 434 *error = StringPrintf( |
| 435 "%s %s", errors::kLocalesMessagesFileMissing, |
| 436 WideToUTF8(messages_path.ToWStringHack()).c_str()); |
| 437 return false; |
| 438 } |
| 439 |
| 440 if (locale_path == default_locale_path) |
| 441 has_default_locale_message_file = true; |
| 442 } while (!(locale_path = locales.Next()).empty()); |
| 443 |
| 444 // Only message file for default locale has to exist. |
| 445 if (!has_default_locale_message_file) { |
| 446 *error = errors::kLocalesNoDefaultMessages; |
| 447 return false; |
| 448 } |
| 449 } |
| 450 |
| 451 return true; |
| 452 } |
| 453 |
| 385 bool CheckForIllegalFilenames(const FilePath& extension_path, | 454 bool CheckForIllegalFilenames(const FilePath& extension_path, |
| 386 std::string* error) { | 455 std::string* error) { |
| 387 // Reserved underscore names. | 456 // Reserved underscore names. |
| 388 static const char* reserved_names[] = { | 457 static const char* reserved_names[] = { |
| 389 Extension::kLocaleFolder, | 458 Extension::kLocaleFolder, |
| 390 "__MACOSX" | 459 "__MACOSX" |
| 391 }; | 460 }; |
| 392 static std::set<std::string> reserved_underscore_names( | 461 static std::set<std::string> reserved_underscore_names( |
| 393 reserved_names, reserved_names + arraysize(reserved_names)); | 462 reserved_names, reserved_names + arraysize(reserved_names)); |
| 394 | 463 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 415 "Filenames starting with \"_\" are reserved for use by the system.", | 484 "Filenames starting with \"_\" are reserved for use by the system.", |
| 416 filename.c_str()); | 485 filename.c_str()); |
| 417 return false; | 486 return false; |
| 418 } | 487 } |
| 419 } | 488 } |
| 420 | 489 |
| 421 return true; | 490 return true; |
| 422 } | 491 } |
| 423 | 492 |
| 424 } // namespace extension_file_util | 493 } // namespace extension_file_util |
| OLD | NEW |