| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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_file_util.h" | 5 #include "chrome/common/extensions/extension_file_util.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 namespace errors = extension_manifest_errors; | 42 namespace errors = extension_manifest_errors; |
| 43 | 43 |
| 44 namespace { | 44 namespace { |
| 45 | 45 |
| 46 const base::FilePath::CharType kTempDirectoryName[] = FILE_PATH_LITERAL("Temp"); | 46 const base::FilePath::CharType kTempDirectoryName[] = FILE_PATH_LITERAL("Temp"); |
| 47 | 47 |
| 48 } // namespace | 48 } // namespace |
| 49 | 49 |
| 50 namespace extension_file_util { | 50 namespace extension_file_util { |
| 51 | 51 |
| 52 // Returns false and sets the error if script file can't be loaded, | |
| 53 // or if it's not UTF-8 encoded. | |
| 54 static bool IsScriptValid(const base::FilePath& path, | |
| 55 const base::FilePath& relative_path, | |
| 56 int message_id, std::string* error); | |
| 57 | |
| 58 base::FilePath InstallExtension(const base::FilePath& unpacked_source_dir, | 52 base::FilePath InstallExtension(const base::FilePath& unpacked_source_dir, |
| 59 const std::string& id, | 53 const std::string& id, |
| 60 const std::string& version, | 54 const std::string& version, |
| 61 const base::FilePath& extensions_dir) { | 55 const base::FilePath& extensions_dir) { |
| 62 base::FilePath extension_dir = extensions_dir.AppendASCII(id); | 56 base::FilePath extension_dir = extensions_dir.AppendASCII(id); |
| 63 base::FilePath version_dir; | 57 base::FilePath version_dir; |
| 64 | 58 |
| 65 // Create the extension directory if it doesn't exist already. | 59 // Create the extension directory if it doesn't exist already. |
| 66 if (!file_util::PathExists(extension_dir)) { | 60 if (!file_util::PathExists(extension_dir)) { |
| 67 if (!file_util::CreateDirectory(extension_dir)) | 61 if (!file_util::CreateDirectory(extension_dir)) |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 } | 241 } |
| 248 | 242 |
| 249 bool ValidateExtension(const Extension* extension, | 243 bool ValidateExtension(const Extension* extension, |
| 250 std::string* error, | 244 std::string* error, |
| 251 std::vector<extensions::InstallWarning>* warnings) { | 245 std::vector<extensions::InstallWarning>* warnings) { |
| 252 // Ask registered manifest handlers to validate their paths. | 246 // Ask registered manifest handlers to validate their paths. |
| 253 if (!extensions::ManifestHandler::ValidateExtension( | 247 if (!extensions::ManifestHandler::ValidateExtension( |
| 254 extension, error, warnings)) | 248 extension, error, warnings)) |
| 255 return false; | 249 return false; |
| 256 | 250 |
| 257 // TODO(yoz): Move this to content scripts manifest handler. | |
| 258 // Validate that claimed script resources actually exist, | |
| 259 // and are UTF-8 encoded. | |
| 260 ExtensionResource::SymlinkPolicy symlink_policy; | |
| 261 if ((extension->creation_flags() & | |
| 262 Extension::FOLLOW_SYMLINKS_ANYWHERE) != 0) { | |
| 263 symlink_policy = ExtensionResource::FOLLOW_SYMLINKS_ANYWHERE; | |
| 264 } else { | |
| 265 symlink_policy = ExtensionResource::SYMLINKS_MUST_RESOLVE_WITHIN_ROOT; | |
| 266 } | |
| 267 | |
| 268 for (size_t i = 0; i < extension->content_scripts().size(); ++i) { | |
| 269 const extensions::UserScript& script = extension->content_scripts()[i]; | |
| 270 | |
| 271 for (size_t j = 0; j < script.js_scripts().size(); j++) { | |
| 272 const extensions::UserScript::File& js_script = script.js_scripts()[j]; | |
| 273 const base::FilePath& path = ExtensionResource::GetFilePath( | |
| 274 js_script.extension_root(), js_script.relative_path(), | |
| 275 symlink_policy); | |
| 276 if (!IsScriptValid(path, js_script.relative_path(), | |
| 277 IDS_EXTENSION_LOAD_JAVASCRIPT_FAILED, error)) | |
| 278 return false; | |
| 279 } | |
| 280 | |
| 281 for (size_t j = 0; j < script.css_scripts().size(); j++) { | |
| 282 const extensions::UserScript::File& css_script = script.css_scripts()[j]; | |
| 283 const base::FilePath& path = ExtensionResource::GetFilePath( | |
| 284 css_script.extension_root(), css_script.relative_path(), | |
| 285 symlink_policy); | |
| 286 if (!IsScriptValid(path, css_script.relative_path(), | |
| 287 IDS_EXTENSION_LOAD_CSS_FAILED, error)) | |
| 288 return false; | |
| 289 } | |
| 290 } | |
| 291 | |
| 292 // Check children of extension root to see if any of them start with _ and is | 251 // Check children of extension root to see if any of them start with _ and is |
| 293 // not on the reserved list. | 252 // not on the reserved list. |
| 294 if (!CheckForIllegalFilenames(extension->path(), error)) { | 253 if (!CheckForIllegalFilenames(extension->path(), error)) { |
| 295 return false; | 254 return false; |
| 296 } | 255 } |
| 297 | 256 |
| 298 // Check that extensions don't include private key files. | 257 // Check that extensions don't include private key files. |
| 299 std::vector<base::FilePath> private_keys = | 258 std::vector<base::FilePath> private_keys = |
| 300 FindPrivateKeyFiles(extension->path()); | 259 FindPrivateKeyFiles(extension->path()); |
| 301 if (extension->creation_flags() & Extension::ERROR_ON_PRIVATE_KEY) { | 260 if (extension->creation_flags() & Extension::ERROR_ON_PRIVATE_KEY) { |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 } | 404 } |
| 446 | 405 |
| 447 // Add @@extension_id reserved message here, so it's available to | 406 // Add @@extension_id reserved message here, so it's available to |
| 448 // non-localized extensions too. | 407 // non-localized extensions too. |
| 449 returnValue->insert( | 408 returnValue->insert( |
| 450 std::make_pair(extensions::MessageBundle::kExtensionIdKey, extension_id)); | 409 std::make_pair(extensions::MessageBundle::kExtensionIdKey, extension_id)); |
| 451 | 410 |
| 452 return returnValue; | 411 return returnValue; |
| 453 } | 412 } |
| 454 | 413 |
| 455 static bool IsScriptValid(const base::FilePath& path, | |
| 456 const base::FilePath& relative_path, | |
| 457 int message_id, | |
| 458 std::string* error) { | |
| 459 std::string content; | |
| 460 if (!file_util::PathExists(path) || | |
| 461 !file_util::ReadFileToString(path, &content)) { | |
| 462 *error = l10n_util::GetStringFUTF8( | |
| 463 message_id, | |
| 464 relative_path.LossyDisplayName()); | |
| 465 return false; | |
| 466 } | |
| 467 | |
| 468 if (!IsStringUTF8(content)) { | |
| 469 *error = l10n_util::GetStringFUTF8( | |
| 470 IDS_EXTENSION_BAD_FILE_ENCODING, | |
| 471 relative_path.LossyDisplayName()); | |
| 472 return false; | |
| 473 } | |
| 474 | |
| 475 return true; | |
| 476 } | |
| 477 | |
| 478 bool CheckForIllegalFilenames(const base::FilePath& extension_path, | 414 bool CheckForIllegalFilenames(const base::FilePath& extension_path, |
| 479 std::string* error) { | 415 std::string* error) { |
| 480 // Reserved underscore names. | 416 // Reserved underscore names. |
| 481 static const base::FilePath::CharType* reserved_names[] = { | 417 static const base::FilePath::CharType* reserved_names[] = { |
| 482 extensions::kLocaleFolder, | 418 extensions::kLocaleFolder, |
| 483 extensions::kPlatformSpecificFolder, | 419 extensions::kPlatformSpecificFolder, |
| 484 FILE_PATH_LITERAL("__MACOSX"), | 420 FILE_PATH_LITERAL("__MACOSX"), |
| 485 }; | 421 }; |
| 486 CR_DEFINE_STATIC_LOCAL( | 422 CR_DEFINE_STATIC_LOCAL( |
| 487 std::set<base::FilePath::StringType>, reserved_underscore_names, | 423 std::set<base::FilePath::StringType>, reserved_underscore_names, |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 return base::FilePath(); | 530 return base::FilePath(); |
| 595 } | 531 } |
| 596 return temp_path; | 532 return temp_path; |
| 597 } | 533 } |
| 598 | 534 |
| 599 void DeleteFile(const base::FilePath& path, bool recursive) { | 535 void DeleteFile(const base::FilePath& path, bool recursive) { |
| 600 file_util::Delete(path, recursive); | 536 file_util::Delete(path, recursive); |
| 601 } | 537 } |
| 602 | 538 |
| 603 } // namespace extension_file_util | 539 } // namespace extension_file_util |
| OLD | NEW |