Index: chrome/common/extensions/extension_file_util.cc |
diff --git a/chrome/common/extensions/extension_file_util.cc b/chrome/common/extensions/extension_file_util.cc |
index f565509c6a46e41452a8296bbbe447266884834d..137536cbf61d2fe26bbe6e2eeaa9d1bd6f0fbd02 100644 |
--- a/chrome/common/extensions/extension_file_util.cc |
+++ b/chrome/common/extensions/extension_file_util.cc |
@@ -36,6 +36,8 @@ namespace errors = extension_manifest_errors; |
namespace { |
+const FilePath::CharType kTempDirectoryName[] = FILE_PATH_LITERAL("Temp"); |
+ |
bool ValidateExtensionIconSet(const ExtensionIconSet& icon_set, |
const Extension* extension, |
int error_message_id, |
@@ -66,13 +68,11 @@ static bool ValidateLocaleInfo(const Extension& extension, |
static bool IsScriptValid(const FilePath& path, const FilePath& relative_path, |
int message_id, std::string* error); |
-const char kInstallDirectoryName[] = "Extensions"; |
- |
FilePath InstallExtension(const FilePath& unpacked_source_dir, |
const std::string& id, |
const std::string& version, |
- const FilePath& all_extensions_dir) { |
- FilePath extension_dir = all_extensions_dir.AppendASCII(id); |
+ const FilePath& extensions_dir) { |
+ FilePath extension_dir = extensions_dir.AppendASCII(id); |
FilePath version_dir; |
// Create the extension directory if it doesn't exist already. |
@@ -81,10 +81,11 @@ FilePath InstallExtension(const FilePath& unpacked_source_dir, |
return FilePath(); |
} |
- FilePath profile_temp_dir = GetUserDataTempDir(); |
+ // Get a temp directory on the same file system as the profile. |
+ FilePath install_temp_dir = GetInstallTempDir(extensions_dir); |
ScopedTempDir extension_temp_dir; |
- if (profile_temp_dir.empty() || |
- !extension_temp_dir.CreateUniqueTempDirUnderPath(profile_temp_dir)) { |
+ if (install_temp_dir.empty() || |
+ !extension_temp_dir.CreateUniqueTempDirUnderPath(install_temp_dir)) { |
LOG(ERROR) << "Creating of temp dir under in the profile failed."; |
return FilePath(); |
} |
@@ -436,6 +437,14 @@ void GarbageCollectExtensions( |
std::string extension_id; |
FilePath basename = extension_path.BaseName(); |
+ // Clean up temporary files left if Chrome crashed or quit in the middle |
+ // of an extension install. |
+ if (basename.value() == kTempDirectoryName) { |
+ file_util::Delete(extension_path, true); // Recursive |
+ continue; |
+ } |
+ |
+ // Parse directory name as a potential extension ID. |
if (IsStringASCII(basename.value())) { |
extension_id = UTF16ToASCII(basename.LossyDisplayName()); |
if (!Extension::IdIsValid(extension_id)) |
@@ -708,68 +717,36 @@ FilePath ExtensionResourceURLToFilePath(const GURL& url, const FilePath& root) { |
return path; |
} |
-FilePath GetUserDataTempDir() { |
+FilePath GetInstallTempDir(const FilePath& extensions_dir) { |
// We do file IO in this function, but only when the current profile's |
// Temp directory has never been used before, or in a rare error case. |
// Developers are not likely to see these situations often, so do an |
// explicit thread check. |
base::ThreadRestrictions::AssertIOAllowed(); |
- // The following enum used to be sent as a histogram to diagnose issues |
- // accessing the temp path (crbug/70056). The histogram is gone, but |
- // the enum makes it clear exactly why the temp directory can not be |
- // accessed, which may aid debugging in the future. |
- enum DirectoryCreationResult { |
- SUCCESS = 0, |
- |
- CANT_GET_PARENT_PATH, |
- CANT_GET_UDT_PATH, |
- NOT_A_DIRECTORY, |
- CANT_CREATE_DIR, |
- CANT_WRITE_TO_PATH, |
- |
- UNSET, |
- NUM_DIRECTORY_CREATION_RESULTS |
- }; |
- |
- // All paths should set |result|. |
- DirectoryCreationResult result = UNSET; |
- |
- FilePath temp_path; |
- if (!PathService::Get(chrome::DIR_USER_DATA_TEMP, &temp_path)) { |
- FilePath parent_path; |
- if (!PathService::Get(chrome::DIR_USER_DATA, &parent_path)) |
- result = CANT_GET_PARENT_PATH; |
- else |
- result = CANT_GET_UDT_PATH; |
- |
- } else if (file_util::PathExists(temp_path)) { |
- |
- // Path exists. Check that it is a directory we can write to. |
+ // Create the temp directory as a sub-directory of the Extensions directory. |
+ // This guarantees it is on the same file system as the extension's eventual |
+ // install target. |
+ FilePath temp_path = extensions_dir.Append(kTempDirectoryName); |
+ if (file_util::PathExists(temp_path)) { |
if (!file_util::DirectoryExists(temp_path)) { |
- result = NOT_A_DIRECTORY; |
- |
- } else if (!file_util::PathIsWritable(temp_path)) { |
- result = CANT_WRITE_TO_PATH; |
- |
- } else { |
- // Temp is a writable directory. |
- result = SUCCESS; |
+ DLOG(WARNING) << "Not a directory: " << temp_path.value(); |
+ return FilePath(); |
} |
- |
- } else if (!file_util::CreateDirectory(temp_path)) { |
- // Path doesn't exist, and we failed to create it. |
- result = CANT_CREATE_DIR; |
- |
- } else { |
- // Successfully created the Temp directory. |
- result = SUCCESS; |
- } |
- |
- if (result == SUCCESS) |
+ if (!file_util::PathIsWritable(temp_path)) { |
+ DLOG(WARNING) << "Can't write to path: " << temp_path.value(); |
+ return FilePath(); |
+ } |
+ // This is a directory we can write to. |
return temp_path; |
+ } |
- return FilePath(); |
+ // Directory doesn't exist, so create it. |
+ if (!file_util::CreateDirectory(temp_path)) { |
+ DLOG(WARNING) << "Couldn't create directory: " << temp_path.value(); |
+ return FilePath(); |
+ } |
+ return temp_path; |
} |
void DeleteFile(const FilePath& path, bool recursive) { |