| 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 namespace extension_file_util { | 65 namespace extension_file_util { |
| 66 | 66 |
| 67 base::FilePath InstallExtension(const base::FilePath& unpacked_source_dir, | 67 base::FilePath InstallExtension(const base::FilePath& unpacked_source_dir, |
| 68 const std::string& id, | 68 const std::string& id, |
| 69 const std::string& version, | 69 const std::string& version, |
| 70 const base::FilePath& extensions_dir) { | 70 const base::FilePath& extensions_dir) { |
| 71 base::FilePath extension_dir = extensions_dir.AppendASCII(id); | 71 base::FilePath extension_dir = extensions_dir.AppendASCII(id); |
| 72 base::FilePath version_dir; | 72 base::FilePath version_dir; |
| 73 | 73 |
| 74 // Create the extension directory if it doesn't exist already. | 74 // Create the extension directory if it doesn't exist already. |
| 75 if (!file_util::PathExists(extension_dir)) { | 75 if (!base::PathExists(extension_dir)) { |
| 76 if (!file_util::CreateDirectory(extension_dir)) | 76 if (!file_util::CreateDirectory(extension_dir)) |
| 77 return base::FilePath(); | 77 return base::FilePath(); |
| 78 } | 78 } |
| 79 | 79 |
| 80 // Get a temp directory on the same file system as the profile. | 80 // Get a temp directory on the same file system as the profile. |
| 81 base::FilePath install_temp_dir = GetInstallTempDir(extensions_dir); | 81 base::FilePath install_temp_dir = GetInstallTempDir(extensions_dir); |
| 82 base::ScopedTempDir extension_temp_dir; | 82 base::ScopedTempDir extension_temp_dir; |
| 83 if (install_temp_dir.empty() || | 83 if (install_temp_dir.empty() || |
| 84 !extension_temp_dir.CreateUniqueTempDirUnderPath(install_temp_dir)) { | 84 !extension_temp_dir.CreateUniqueTempDirUnderPath(install_temp_dir)) { |
| 85 LOG(ERROR) << "Creating of temp dir under in the profile failed."; | 85 LOG(ERROR) << "Creating of temp dir under in the profile failed."; |
| 86 return base::FilePath(); | 86 return base::FilePath(); |
| 87 } | 87 } |
| 88 base::FilePath crx_temp_source = | 88 base::FilePath crx_temp_source = |
| 89 extension_temp_dir.path().Append(unpacked_source_dir.BaseName()); | 89 extension_temp_dir.path().Append(unpacked_source_dir.BaseName()); |
| 90 if (!base::Move(unpacked_source_dir, crx_temp_source)) { | 90 if (!base::Move(unpacked_source_dir, crx_temp_source)) { |
| 91 LOG(ERROR) << "Moving extension from : " << unpacked_source_dir.value() | 91 LOG(ERROR) << "Moving extension from : " << unpacked_source_dir.value() |
| 92 << " to : " << crx_temp_source.value() << " failed."; | 92 << " to : " << crx_temp_source.value() << " failed."; |
| 93 return base::FilePath(); | 93 return base::FilePath(); |
| 94 } | 94 } |
| 95 | 95 |
| 96 // Try to find a free directory. There can be legitimate conflicts in the case | 96 // Try to find a free directory. There can be legitimate conflicts in the case |
| 97 // of overinstallation of the same version. | 97 // of overinstallation of the same version. |
| 98 const int kMaxAttempts = 100; | 98 const int kMaxAttempts = 100; |
| 99 for (int i = 0; i < kMaxAttempts; ++i) { | 99 for (int i = 0; i < kMaxAttempts; ++i) { |
| 100 base::FilePath candidate = extension_dir.AppendASCII( | 100 base::FilePath candidate = extension_dir.AppendASCII( |
| 101 base::StringPrintf("%s_%u", version.c_str(), i)); | 101 base::StringPrintf("%s_%u", version.c_str(), i)); |
| 102 if (!file_util::PathExists(candidate)) { | 102 if (!base::PathExists(candidate)) { |
| 103 version_dir = candidate; | 103 version_dir = candidate; |
| 104 break; | 104 break; |
| 105 } | 105 } |
| 106 } | 106 } |
| 107 | 107 |
| 108 if (version_dir.empty()) { | 108 if (version_dir.empty()) { |
| 109 LOG(ERROR) << "Could not find a home for extension " << id << " with " | 109 LOG(ERROR) << "Could not find a home for extension " << id << " with " |
| 110 << "version " << version << "."; | 110 << "version " << version << "."; |
| 111 return base::FilePath(); | 111 return base::FilePath(); |
| 112 } | 112 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 return NULL; | 163 return NULL; |
| 164 extension->AddInstallWarnings(warnings); | 164 extension->AddInstallWarnings(warnings); |
| 165 | 165 |
| 166 return extension; | 166 return extension; |
| 167 } | 167 } |
| 168 | 168 |
| 169 base::DictionaryValue* LoadManifest(const base::FilePath& extension_path, | 169 base::DictionaryValue* LoadManifest(const base::FilePath& extension_path, |
| 170 std::string* error) { | 170 std::string* error) { |
| 171 base::FilePath manifest_path = | 171 base::FilePath manifest_path = |
| 172 extension_path.Append(extensions::kManifestFilename); | 172 extension_path.Append(extensions::kManifestFilename); |
| 173 if (!file_util::PathExists(manifest_path)) { | 173 if (!base::PathExists(manifest_path)) { |
| 174 *error = l10n_util::GetStringUTF8(IDS_EXTENSION_MANIFEST_UNREADABLE); | 174 *error = l10n_util::GetStringUTF8(IDS_EXTENSION_MANIFEST_UNREADABLE); |
| 175 return NULL; | 175 return NULL; |
| 176 } | 176 } |
| 177 | 177 |
| 178 JSONFileValueSerializer serializer(manifest_path); | 178 JSONFileValueSerializer serializer(manifest_path); |
| 179 scoped_ptr<base::Value> root(serializer.Deserialize(NULL, error)); | 179 scoped_ptr<base::Value> root(serializer.Deserialize(NULL, error)); |
| 180 if (!root.get()) { | 180 if (!root.get()) { |
| 181 if (error->empty()) { | 181 if (error->empty()) { |
| 182 // If |error| is empty, than the file could not be read. | 182 // If |error| is empty, than the file could not be read. |
| 183 // It would be cleaner to have the JSON reader give a specific error | 183 // It would be cleaner to have the JSON reader give a specific error |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 continue; | 222 continue; |
| 223 } | 223 } |
| 224 | 224 |
| 225 result.push_back(current); | 225 result.push_back(current); |
| 226 } | 226 } |
| 227 return result; | 227 return result; |
| 228 } | 228 } |
| 229 | 229 |
| 230 bool ValidateFilePath(const base::FilePath& path) { | 230 bool ValidateFilePath(const base::FilePath& path) { |
| 231 int64 size = 0; | 231 int64 size = 0; |
| 232 if (!file_util::PathExists(path) || | 232 if (!base::PathExists(path) || |
| 233 !file_util::GetFileSize(path, &size) || | 233 !file_util::GetFileSize(path, &size) || |
| 234 size == 0) { | 234 size == 0) { |
| 235 return false; | 235 return false; |
| 236 } | 236 } |
| 237 | 237 |
| 238 return true; | 238 return true; |
| 239 } | 239 } |
| 240 | 240 |
| 241 bool ValidateExtensionIconSet(const ExtensionIconSet& icon_set, | 241 bool ValidateExtensionIconSet(const ExtensionIconSet& icon_set, |
| 242 const Extension* extension, | 242 const Extension* extension, |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 } | 402 } |
| 403 } | 403 } |
| 404 | 404 |
| 405 extensions::MessageBundle* LoadMessageBundle( | 405 extensions::MessageBundle* LoadMessageBundle( |
| 406 const base::FilePath& extension_path, | 406 const base::FilePath& extension_path, |
| 407 const std::string& default_locale, | 407 const std::string& default_locale, |
| 408 std::string* error) { | 408 std::string* error) { |
| 409 error->clear(); | 409 error->clear(); |
| 410 // Load locale information if available. | 410 // Load locale information if available. |
| 411 base::FilePath locale_path = extension_path.Append(extensions::kLocaleFolder); | 411 base::FilePath locale_path = extension_path.Append(extensions::kLocaleFolder); |
| 412 if (!file_util::PathExists(locale_path)) | 412 if (!base::PathExists(locale_path)) |
| 413 return NULL; | 413 return NULL; |
| 414 | 414 |
| 415 std::set<std::string> locales; | 415 std::set<std::string> locales; |
| 416 if (!extension_l10n_util::GetValidLocales(locale_path, &locales, error)) | 416 if (!extension_l10n_util::GetValidLocales(locale_path, &locales, error)) |
| 417 return NULL; | 417 return NULL; |
| 418 | 418 |
| 419 if (default_locale.empty() || | 419 if (default_locale.empty() || |
| 420 locales.find(default_locale) == locales.end()) { | 420 locales.find(default_locale) == locales.end()) { |
| 421 *error = l10n_util::GetStringUTF8( | 421 *error = l10n_util::GetStringUTF8( |
| 422 IDS_EXTENSION_LOCALES_NO_DEFAULT_LOCALE_SPECIFIED); | 422 IDS_EXTENSION_LOCALES_NO_DEFAULT_LOCALE_SPECIFIED); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 std::string host = net::UnescapeURLComponent(url.host(), | 522 std::string host = net::UnescapeURLComponent(url.host(), |
| 523 net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS); | 523 net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS); |
| 524 if (host.empty()) | 524 if (host.empty()) |
| 525 return base::FilePath(); | 525 return base::FilePath(); |
| 526 | 526 |
| 527 base::FilePath relative_path = ExtensionURLToRelativeFilePath(url); | 527 base::FilePath relative_path = ExtensionURLToRelativeFilePath(url); |
| 528 if (relative_path.empty()) | 528 if (relative_path.empty()) |
| 529 return base::FilePath(); | 529 return base::FilePath(); |
| 530 | 530 |
| 531 base::FilePath path = root.AppendASCII(host).Append(relative_path); | 531 base::FilePath path = root.AppendASCII(host).Append(relative_path); |
| 532 if (!file_util::PathExists(path)) | 532 if (!base::PathExists(path)) |
| 533 return base::FilePath(); | 533 return base::FilePath(); |
| 534 path = base::MakeAbsoluteFilePath(path); | 534 path = base::MakeAbsoluteFilePath(path); |
| 535 if (path.empty() || !root.IsParent(path)) | 535 if (path.empty() || !root.IsParent(path)) |
| 536 return base::FilePath(); | 536 return base::FilePath(); |
| 537 return path; | 537 return path; |
| 538 } | 538 } |
| 539 | 539 |
| 540 base::FilePath GetInstallTempDir(const base::FilePath& extensions_dir) { | 540 base::FilePath GetInstallTempDir(const base::FilePath& extensions_dir) { |
| 541 // We do file IO in this function, but only when the current profile's | 541 // We do file IO in this function, but only when the current profile's |
| 542 // Temp directory has never been used before, or in a rare error case. | 542 // Temp directory has never been used before, or in a rare error case. |
| 543 // Developers are not likely to see these situations often, so do an | 543 // Developers are not likely to see these situations often, so do an |
| 544 // explicit thread check. | 544 // explicit thread check. |
| 545 base::ThreadRestrictions::AssertIOAllowed(); | 545 base::ThreadRestrictions::AssertIOAllowed(); |
| 546 | 546 |
| 547 // Create the temp directory as a sub-directory of the Extensions directory. | 547 // Create the temp directory as a sub-directory of the Extensions directory. |
| 548 // This guarantees it is on the same file system as the extension's eventual | 548 // This guarantees it is on the same file system as the extension's eventual |
| 549 // install target. | 549 // install target. |
| 550 base::FilePath temp_path = extensions_dir.Append(kTempDirectoryName); | 550 base::FilePath temp_path = extensions_dir.Append(kTempDirectoryName); |
| 551 if (file_util::PathExists(temp_path)) { | 551 if (base::PathExists(temp_path)) { |
| 552 if (!file_util::DirectoryExists(temp_path)) { | 552 if (!file_util::DirectoryExists(temp_path)) { |
| 553 DLOG(WARNING) << "Not a directory: " << temp_path.value(); | 553 DLOG(WARNING) << "Not a directory: " << temp_path.value(); |
| 554 return base::FilePath(); | 554 return base::FilePath(); |
| 555 } | 555 } |
| 556 if (!file_util::PathIsWritable(temp_path)) { | 556 if (!file_util::PathIsWritable(temp_path)) { |
| 557 DLOG(WARNING) << "Can't write to path: " << temp_path.value(); | 557 DLOG(WARNING) << "Can't write to path: " << temp_path.value(); |
| 558 return base::FilePath(); | 558 return base::FilePath(); |
| 559 } | 559 } |
| 560 // This is a directory we can write to. | 560 // This is a directory we can write to. |
| 561 return temp_path; | 561 return temp_path; |
| 562 } | 562 } |
| 563 | 563 |
| 564 // Directory doesn't exist, so create it. | 564 // Directory doesn't exist, so create it. |
| 565 if (!file_util::CreateDirectory(temp_path)) { | 565 if (!file_util::CreateDirectory(temp_path)) { |
| 566 DLOG(WARNING) << "Couldn't create directory: " << temp_path.value(); | 566 DLOG(WARNING) << "Couldn't create directory: " << temp_path.value(); |
| 567 return base::FilePath(); | 567 return base::FilePath(); |
| 568 } | 568 } |
| 569 return temp_path; | 569 return temp_path; |
| 570 } | 570 } |
| 571 | 571 |
| 572 void DeleteFile(const base::FilePath& path, bool recursive) { | 572 void DeleteFile(const base::FilePath& path, bool recursive) { |
| 573 base::Delete(path, recursive); | 573 base::Delete(path, recursive); |
| 574 } | 574 } |
| 575 | 575 |
| 576 } // namespace extension_file_util | 576 } // namespace extension_file_util |
| OLD | NEW |