| 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 |
| 23 // Validates locale info. Doesn't check if messages.json files are valid. |
| 24 static bool ValidateLocaleInfo(const Extension& extension, std::string* error); |
| 25 |
| 21 const char kInstallDirectoryName[] = "Extensions"; | 26 const char kInstallDirectoryName[] = "Extensions"; |
| 22 // TODO(mpcomplete): obsolete. remove after migration period. | 27 // TODO(mpcomplete): obsolete. remove after migration period. |
| 23 // http://code.google.com/p/chromium/issues/detail?id=19733 | 28 // http://code.google.com/p/chromium/issues/detail?id=19733 |
| 24 const char kCurrentVersionFileName[] = "Current Version"; | 29 const char kCurrentVersionFileName[] = "Current Version"; |
| 25 | 30 |
| 26 bool MoveDirSafely(const FilePath& source_dir, const FilePath& dest_dir) { | 31 bool MoveDirSafely(const FilePath& source_dir, const FilePath& dest_dir) { |
| 27 if (file_util::PathExists(dest_dir)) { | 32 if (file_util::PathExists(dest_dir)) { |
| 28 if (!file_util::Delete(dest_dir, true)) | 33 if (!file_util::Delete(dest_dir, true)) |
| 29 return false; | 34 return false; |
| 30 } else { | 35 } else { |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 if (!extension->background_url().is_empty()) { | 268 if (!extension->background_url().is_empty()) { |
| 264 const std::string page_path = extension->background_url().path(); | 269 const std::string page_path = extension->background_url().path(); |
| 265 const FilePath path = extension->GetResource(page_path).GetFilePath(); | 270 const FilePath path = extension->GetResource(page_path).GetFilePath(); |
| 266 if (!file_util::PathExists(path)) { | 271 if (!file_util::PathExists(path)) { |
| 267 *error = StringPrintf("Could not load background page '%s'.", | 272 *error = StringPrintf("Could not load background page '%s'.", |
| 268 WideToUTF8(path.ToWStringHack()).c_str()); | 273 WideToUTF8(path.ToWStringHack()).c_str()); |
| 269 return false; | 274 return false; |
| 270 } | 275 } |
| 271 } | 276 } |
| 272 | 277 |
| 278 // Validate locale info. |
| 279 if (!ValidateLocaleInfo(*extension, error)) |
| 280 return false; |
| 281 |
| 273 // Check children of extension root to see if any of them start with _ and is | 282 // Check children of extension root to see if any of them start with _ and is |
| 274 // not on the reserved list. | 283 // not on the reserved list. |
| 275 if (!CheckForIllegalFilenames(extension->path(), error)) { | 284 if (!CheckForIllegalFilenames(extension->path(), error)) { |
| 276 return false; | 285 return false; |
| 277 } | 286 } |
| 278 | 287 |
| 279 return true; | 288 return true; |
| 280 } | 289 } |
| 281 | 290 |
| 282 void UninstallExtension(const std::string& id, const FilePath& extensions_dir) { | 291 void UninstallExtension(const std::string& id, const FilePath& extensions_dir) { |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 app_locale = ""; | 409 app_locale = ""; |
| 401 ExtensionMessageBundle* message_bundle = | 410 ExtensionMessageBundle* message_bundle = |
| 402 extension_l10n_util::LoadMessageCatalogs(locale_path, | 411 extension_l10n_util::LoadMessageCatalogs(locale_path, |
| 403 default_locale, | 412 default_locale, |
| 404 app_locale, | 413 app_locale, |
| 405 locales, | 414 locales, |
| 406 error); | 415 error); |
| 407 return message_bundle; | 416 return message_bundle; |
| 408 } | 417 } |
| 409 | 418 |
| 419 static bool ValidateLocaleInfo(const Extension& extension, std::string* error) { |
| 420 // default_locale and _locales have to be both present or both missing. |
| 421 const FilePath path = extension.path().AppendASCII(Extension::kLocaleFolder); |
| 422 bool path_exists = file_util::PathExists(path); |
| 423 std::string default_locale = extension.default_locale(); |
| 424 |
| 425 // If both default locale and _locales folder are empty, skip verification. |
| 426 if (!default_locale.empty() || path_exists) { |
| 427 if (default_locale.empty() && path_exists) { |
| 428 *error = errors::kLocalesNoDefaultLocaleSpecified; |
| 429 return false; |
| 430 } else if (!default_locale.empty() && !path_exists) { |
| 431 *error = errors::kLocalesTreeMissing; |
| 432 return false; |
| 433 } |
| 434 |
| 435 // Treat all folders under _locales as valid locales. |
| 436 file_util::FileEnumerator locales(path, |
| 437 false, |
| 438 file_util::FileEnumerator::DIRECTORIES); |
| 439 |
| 440 FilePath locale_path = locales.Next(); |
| 441 if (locale_path.empty()) { |
| 442 *error = errors::kLocalesTreeMissing; |
| 443 return false; |
| 444 } |
| 445 |
| 446 const FilePath default_locale_path = path.AppendASCII(default_locale); |
| 447 bool has_default_locale_message_file = false; |
| 448 do { |
| 449 // Skip any strings with '.'. This happens sometimes, for example with |
| 450 // '.svn' directories. |
| 451 FilePath relative_path; |
| 452 if (!extension.path().AppendRelativePath(locale_path, &relative_path)) |
| 453 NOTREACHED(); |
| 454 std::wstring subdir(relative_path.ToWStringHack()); |
| 455 if (std::find(subdir.begin(), subdir.end(), L'.') != subdir.end()) |
| 456 continue; |
| 457 |
| 458 FilePath messages_path = |
| 459 locale_path.AppendASCII(Extension::kMessagesFilename); |
| 460 |
| 461 if (!file_util::PathExists(messages_path)) { |
| 462 *error = StringPrintf( |
| 463 "%s %s", errors::kLocalesMessagesFileMissing, |
| 464 WideToUTF8(messages_path.ToWStringHack()).c_str()); |
| 465 return false; |
| 466 } |
| 467 |
| 468 if (locale_path == default_locale_path) |
| 469 has_default_locale_message_file = true; |
| 470 } while (!(locale_path = locales.Next()).empty()); |
| 471 |
| 472 // Only message file for default locale has to exist. |
| 473 if (!has_default_locale_message_file) { |
| 474 *error = errors::kLocalesNoDefaultMessages; |
| 475 return false; |
| 476 } |
| 477 } |
| 478 |
| 479 return true; |
| 480 } |
| 481 |
| 410 bool CheckForIllegalFilenames(const FilePath& extension_path, | 482 bool CheckForIllegalFilenames(const FilePath& extension_path, |
| 411 std::string* error) { | 483 std::string* error) { |
| 412 // Reserved underscore names. | 484 // Reserved underscore names. |
| 413 static const char* reserved_names[] = { | 485 static const char* reserved_names[] = { |
| 414 Extension::kLocaleFolder, | 486 Extension::kLocaleFolder, |
| 415 "__MACOSX" | 487 "__MACOSX" |
| 416 }; | 488 }; |
| 417 static std::set<std::string> reserved_underscore_names( | 489 static std::set<std::string> reserved_underscore_names( |
| 418 reserved_names, reserved_names + arraysize(reserved_names)); | 490 reserved_names, reserved_names + arraysize(reserved_names)); |
| 419 | 491 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 440 "Filenames starting with \"_\" are reserved for use by the system.", | 512 "Filenames starting with \"_\" are reserved for use by the system.", |
| 441 filename.c_str()); | 513 filename.c_str()); |
| 442 return false; | 514 return false; |
| 443 } | 515 } |
| 444 } | 516 } |
| 445 | 517 |
| 446 return true; | 518 return true; |
| 447 } | 519 } |
| 448 | 520 |
| 449 } // namespace extension_file_util | 521 } // namespace extension_file_util |
| OLD | NEW |