diff options
-rw-r--r-- | base/file_util.h | 7 | ||||
-rw-r--r-- | base/file_util_posix.cc | 37 | ||||
-rw-r--r-- | base/file_util_unittest.cc | 11 | ||||
-rw-r--r-- | base/file_util_win.cc | 25 | ||||
-rw-r--r-- | base/scoped_temp_dir.cc | 15 | ||||
-rw-r--r-- | base/scoped_temp_dir.h | 3 | ||||
-rw-r--r-- | base/scoped_temp_dir_unittest.cc | 18 | ||||
-rw-r--r-- | chrome/browser/extensions/crx_installer.cc | 6 | ||||
-rw-r--r-- | chrome/browser/extensions/sandboxed_extension_unpacker.cc | 14 | ||||
-rw-r--r-- | chrome/browser/extensions/sandboxed_extension_unpacker.h | 4 | ||||
-rw-r--r-- | chrome/browser/extensions/sandboxed_extension_unpacker_unittest.cc | 42 | ||||
-rw-r--r-- | chrome/common/chrome_paths.cc | 6 | ||||
-rw-r--r-- | chrome/common/chrome_paths.h | 4 | ||||
-rw-r--r-- | chrome/common/extensions/extension_constants.cc | 11 | ||||
-rw-r--r-- | chrome/common/extensions/extension_constants.h | 13 | ||||
-rw-r--r-- | chrome/common/extensions/extension_file_util.h | 2 | ||||
-rw-r--r-- | chrome/common/extensions/extension_unpacker.cc | 23 |
17 files changed, 198 insertions, 43 deletions
diff --git a/base/file_util.h b/base/file_util.h index 96891e6..467b404 100644 --- a/base/file_util.h +++ b/base/file_util.h @@ -249,6 +249,13 @@ FILE* CreateAndOpenTemporaryFileInDir(const FilePath& dir, FilePath* path); bool CreateTemporaryFileInDir(const FilePath& dir, FilePath* temp_file); +// Create a directory within another directory. +// Extra characters will be appended to |name_tmpl| to ensure that the +// new directory does not have the same name as an existing directory. +bool CreateTemporaryDirInDir(const FilePath& base_dir, + const FilePath::StringType& prefix, + FilePath* new_dir); + // Create a new directory under TempPath. If prefix is provided, the new // directory name is in the format of prefixyyyy. // NOTE: prefix is ignored in the POSIX implementation. diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc index 4d4e572..d9cbe09 100644 --- a/base/file_util_posix.cc +++ b/base/file_util_posix.cc @@ -401,22 +401,41 @@ bool CreateTemporaryFileInDir(const FilePath& dir, FilePath* temp_file) { return ((fd >= 0) && !close(fd)); } -bool CreateNewTempDirectory(const FilePath::StringType& prefix, - FilePath* new_temp_path) { - FilePath tmpdir; - if (!GetTempDir(&tmpdir)) - return false; - tmpdir = tmpdir.Append(kTempFileName); - std::string tmpdir_string = tmpdir.value(); +static bool CreateTemporaryDirInDirImpl(const FilePath& base_dir, + const FilePath::StringType& name_tmpl, + FilePath* new_dir) { + CHECK(name_tmpl.find("XXXXXX") != FilePath::StringType::npos) + << "Directory name template must contain \"XXXXXX\"."; + + FilePath sub_dir = base_dir.Append(name_tmpl); + std::string sub_dir_string = sub_dir.value(); + // this should be OK since mkdtemp just replaces characters in place - char* buffer = const_cast<char*>(tmpdir_string.c_str()); + char* buffer = const_cast<char*>(sub_dir_string.c_str()); char* dtemp = mkdtemp(buffer); if (!dtemp) return false; - *new_temp_path = FilePath(dtemp); + *new_dir = FilePath(dtemp); return true; } +bool CreateTemporaryDirInDir(const FilePath& base_dir, + const FilePath::StringType& prefix, + FilePath* new_dir) { + FilePath::StringType mkdtemp_template = prefix; + mkdtemp_template.append(FILE_PATH_LITERAL("XXXXXX")); + return CreateTemporaryDirInDirImpl(base_dir, mkdtemp_template, new_dir); +} + +bool CreateNewTempDirectory(const FilePath::StringType& prefix, + FilePath* new_temp_path) { + FilePath tmpdir; + if (!GetTempDir(&tmpdir)) + return false; + + return CreateTemporaryDirInDirImpl(tmpdir, kTempFileName, new_temp_path); +} + bool CreateDirectory(const FilePath& full_path) { std::vector<FilePath> subpaths; diff --git a/base/file_util_unittest.cc b/base/file_util_unittest.cc index c46c39f..25b93e1 100644 --- a/base/file_util_unittest.cc +++ b/base/file_util_unittest.cc @@ -1141,6 +1141,17 @@ TEST_F(FileUtilTest, CreateNewTempDirectoryTest) { EXPECT_TRUE(file_util::Delete(temp_dir, false)); } +TEST_F(FileUtilTest, CreateNewTemporaryDirInDirTest) { + FilePath new_dir; + ASSERT_TRUE(file_util::CreateTemporaryDirInDir( + test_dir_, + FILE_PATH_LITERAL("CreateNewTemporaryDirInDirTest"), + &new_dir)); + EXPECT_TRUE(file_util::PathExists(new_dir)); + EXPECT_TRUE(test_dir_.IsParent(new_dir)); + EXPECT_TRUE(file_util::Delete(new_dir, false)); +} + TEST_F(FileUtilTest, GetShmemTempDirTest) { FilePath dir; EXPECT_TRUE(file_util::GetShmemTempDir(&dir)); diff --git a/base/file_util_win.cc b/base/file_util_win.cc index d1cdc6c..445f82e 100644 --- a/base/file_util_win.cc +++ b/base/file_util_win.cc @@ -500,12 +500,9 @@ bool CreateTemporaryFileInDir(const FilePath& dir, return true; } -bool CreateNewTempDirectory(const FilePath::StringType& prefix, - FilePath* new_temp_path) { - FilePath system_temp_dir; - if (!GetTempDir(&system_temp_dir)) - return false; - +bool CreateTemporaryDirInDir(const FilePath& base_dir, + const FilePath::StringType& prefix, + FilePath* new_dir) { FilePath path_to_create; srand(static_cast<uint32>(time(NULL))); @@ -513,12 +510,13 @@ bool CreateNewTempDirectory(const FilePath::StringType& prefix, while (count < 50) { // Try create a new temporary directory with random generated name. If // the one exists, keep trying another path name until we reach some limit. - path_to_create = system_temp_dir; + path_to_create = base_dir; + std::wstring new_dir_name; new_dir_name.assign(prefix); new_dir_name.append(IntToWString(rand() % kint16max)); - path_to_create = path_to_create.Append(new_dir_name); + path_to_create = path_to_create.Append(new_dir_name); if (::CreateDirectory(path_to_create.value().c_str(), NULL)) break; count++; @@ -528,10 +526,19 @@ bool CreateNewTempDirectory(const FilePath::StringType& prefix, return false; } - *new_temp_path = path_to_create; + *new_dir = path_to_create; return true; } +bool CreateNewTempDirectory(const FilePath::StringType& prefix, + FilePath* new_temp_path) { + FilePath system_temp_dir; + if (!GetTempDir(&system_temp_dir)) + return false; + + return CreateTemporaryDirInDir(system_temp_dir, prefix, new_temp_path); +} + bool CreateDirectory(const FilePath& full_path) { // If the path exists, we've succeeded if it's a directory, failed otherwise. const wchar_t* full_path_str = full_path.value().c_str(); diff --git a/base/scoped_temp_dir.cc b/base/scoped_temp_dir.cc index 07fcfb7..c8ed9c6 100644 --- a/base/scoped_temp_dir.cc +++ b/base/scoped_temp_dir.cc @@ -26,6 +26,21 @@ bool ScopedTempDir::CreateUniqueTempDir() { return true; } +bool ScopedTempDir::CreateUniqueTempDirUnderPath(const FilePath& base_path) { + // If |path| does not exist, create it. + if (!file_util::CreateDirectory(base_path)) + return false; + + // Create a new, uniquly named directory under |base_path|. + if (!file_util::CreateTemporaryDirInDir( + base_path, + FILE_PATH_LITERAL("scoped_dir_"), + &path_)) { + return false; + } + return true; +} + bool ScopedTempDir::Set(const FilePath& path) { DCHECK(path_.empty()); if (!file_util::DirectoryExists(path) && diff --git a/base/scoped_temp_dir.h b/base/scoped_temp_dir.h index e9d45b9..a5dca1e 100644 --- a/base/scoped_temp_dir.h +++ b/base/scoped_temp_dir.h @@ -25,6 +25,9 @@ class ScopedTempDir { // See file_util::CreateNewTemporaryDirectory. bool CreateUniqueTempDir(); + // Creates a unique directory under a given path, and takes ownership of it. + bool CreateUniqueTempDirUnderPath(const FilePath& path); + // Takes ownership of directory at |path|, creating it if necessary. // Don't call multiple times unless Take() has been called first. bool Set(const FilePath& path); diff --git a/base/scoped_temp_dir_unittest.cc b/base/scoped_temp_dir_unittest.cc index 72f4d8c..4be0d07 100644 --- a/base/scoped_temp_dir_unittest.cc +++ b/base/scoped_temp_dir_unittest.cc @@ -55,3 +55,21 @@ TEST(ScopedTempDir, TempDir) { } EXPECT_FALSE(file_util::DirectoryExists(test_path)); } + +TEST(ScopedTempDir, UniqueTempDirUnderPath) { + // Create a path which will contain a unique temp path. + FilePath base_path; + file_util::CreateNewTempDirectory(FILE_PATH_LITERAL("base_dir"), + &base_path); + + FilePath test_path; + { + ScopedTempDir dir; + EXPECT_TRUE(dir.CreateUniqueTempDirUnderPath(base_path)); + test_path = dir.path(); + EXPECT_TRUE(file_util::DirectoryExists(test_path)); + EXPECT_TRUE(base_path.IsParent(test_path)); + EXPECT_TRUE(test_path.value().find(base_path.value()) != std::string::npos); + } + EXPECT_FALSE(file_util::DirectoryExists(test_path)); +} diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc index feb5753..f49db95 100644 --- a/chrome/browser/extensions/crx_installer.cc +++ b/chrome/browser/extensions/crx_installer.cc @@ -7,6 +7,7 @@ #include "app/l10n_util.h" #include "app/resource_bundle.h" #include "base/file_util.h" +#include "base/path_service.h" #include "base/scoped_temp_dir.h" #include "base/task.h" #include "base/utf_string_conversions.h" @@ -17,6 +18,7 @@ #include "chrome/browser/profile.h" #include "chrome/browser/shell_integration.h" #include "chrome/browser/web_applications/web_app.h" +#include "chrome/common/chrome_paths.h" #include "chrome/common/extensions/extension_file_util.h" #include "chrome/common/notification_service.h" #include "chrome/common/notification_type.h" @@ -70,9 +72,13 @@ CrxInstaller::~CrxInstaller() { void CrxInstaller::InstallCrx(const FilePath& source_file) { source_file_ = source_file; + FilePath user_data_temp_dir; + CHECK(PathService::Get(chrome::DIR_USER_DATA_TEMP, &user_data_temp_dir)); + scoped_refptr<SandboxedExtensionUnpacker> unpacker( new SandboxedExtensionUnpacker( source_file, + user_data_temp_dir, g_browser_process->resource_dispatcher_host(), this)); diff --git a/chrome/browser/extensions/sandboxed_extension_unpacker.cc b/chrome/browser/extensions/sandboxed_extension_unpacker.cc index a976400..9df675c 100644 --- a/chrome/browser/extensions/sandboxed_extension_unpacker.cc +++ b/chrome/browser/extensions/sandboxed_extension_unpacker.cc @@ -28,10 +28,13 @@ const char SandboxedExtensionUnpacker::kExtensionHeaderMagic[] = "Cr24"; SandboxedExtensionUnpacker::SandboxedExtensionUnpacker( - const FilePath& crx_path, ResourceDispatcherHost* rdh, + const FilePath& crx_path, + const FilePath& temp_path, + ResourceDispatcherHost* rdh, SandboxedExtensionUnpackerClient* client) - : crx_path_(crx_path), thread_identifier_(ChromeThread::ID_COUNT), - rdh_(rdh), client_(client), got_response_(false) { + : crx_path_(crx_path), temp_path_(temp_path), + thread_identifier_(ChromeThread::ID_COUNT), + rdh_(rdh), client_(client), got_response_(false) { } void SandboxedExtensionUnpacker::Start() { @@ -40,13 +43,14 @@ void SandboxedExtensionUnpacker::Start() { CHECK(ChromeThread::GetCurrentThreadIdentifier(&thread_identifier_)); // Create a temporary directory to work in. - if (!temp_dir_.CreateUniqueTempDir()) { + if (!temp_dir_.CreateUniqueTempDirUnderPath(temp_path_)) { ReportFailure("Could not create temporary directory."); return; } // Initialize the path that will eventually contain the unpacked extension. - extension_root_ = temp_dir_.path().AppendASCII("TEMP_INSTALL"); + extension_root_ = temp_dir_.path().AppendASCII( + extension_filenames::kTempExtensionName); // Extract the public key and validate the package. if (!ValidateSignature()) diff --git a/chrome/browser/extensions/sandboxed_extension_unpacker.h b/chrome/browser/extensions/sandboxed_extension_unpacker.h index a3b190c..42a334061 100644 --- a/chrome/browser/extensions/sandboxed_extension_unpacker.h +++ b/chrome/browser/extensions/sandboxed_extension_unpacker.h @@ -93,6 +93,7 @@ class SandboxedExtensionUnpacker : public UtilityProcessHost::Client { // |client| with the result. If |rdh| is provided, unpacking is done in a // sandboxed subprocess. Otherwise, it is done in-process. SandboxedExtensionUnpacker(const FilePath& crx_path, + const FilePath& temp_path, ResourceDispatcherHost* rdh, SandboxedExtensionUnpackerClient* cilent); @@ -145,6 +146,9 @@ class SandboxedExtensionUnpacker : public UtilityProcessHost::Client { // The path to the CRX to unpack. FilePath crx_path_; + // A path to a temp dir to unpack in. + FilePath temp_path_; + // Our client's thread. This is the thread we respond on. ChromeThread::ID thread_identifier_; diff --git a/chrome/browser/extensions/sandboxed_extension_unpacker_unittest.cc b/chrome/browser/extensions/sandboxed_extension_unpacker_unittest.cc index f320cc0..748cd46 100644 --- a/chrome/browser/extensions/sandboxed_extension_unpacker_unittest.cc +++ b/chrome/browser/extensions/sandboxed_extension_unpacker_unittest.cc @@ -87,15 +87,20 @@ class SandboxedExtensionUnpackerTest : public testing::Test { unpacker_.reset(new ExtensionUnpacker(crx_path)); - // It will delete itself. + + // Build a temp area where the extension will be unpacked. + ASSERT_TRUE(PathService::Get(base::DIR_TEMP, &temp_dir_)); + temp_dir_ = temp_dir_.AppendASCII("sandboxed_extension_unpacker_test_Temp"); + file_util::CreateDirectory(temp_dir_); + sandboxed_unpacker_ = - new SandboxedExtensionUnpacker(crx_path, NULL, client_); + new SandboxedExtensionUnpacker(crx_path, temp_dir_, NULL, client_); PrepareUnpackerEnv(); } void PrepareUnpackerEnv() { sandboxed_unpacker_->extension_root_ = - install_dir_.AppendASCII("TEMP_INSTALL"); + install_dir_.AppendASCII(extension_filenames::kTempExtensionName); sandboxed_unpacker_->temp_dir_.Set(install_dir_); sandboxed_unpacker_->public_key_ = @@ -108,11 +113,36 @@ class SandboxedExtensionUnpackerTest : public testing::Test { } FilePath GetInstallPath() { - return install_dir_.AppendASCII("TEMP_INSTALL"); + return install_dir_.AppendASCII(extension_filenames::kTempExtensionName); + } + + bool TempFilesRemoved() { + // Check that temporary files were cleaned up. + file_util::FileEnumerator::FILE_TYPE files_and_dirs = + static_cast<file_util::FileEnumerator::FILE_TYPE>( + file_util::FileEnumerator::DIRECTORIES | + file_util::FileEnumerator::FILES); + + file_util::FileEnumerator temp_iterator( + temp_dir_, + true, // recursive + files_and_dirs + ); + int items_not_removed = 0; + FilePath item_in_temp; + item_in_temp = temp_iterator.Next(); + while (!item_in_temp.value().empty()) { + items_not_removed++; + EXPECT_STREQ(FILE_PATH_LITERAL(""), item_in_temp.value().c_str()) + << "File was not removed on success."; + item_in_temp = temp_iterator.Next(); + } + return (items_not_removed == 0); } protected: FilePath install_dir_; + FilePath temp_dir_; MockSandboxedExtensionUnpackerClient* client_; scoped_ptr<ExtensionUnpacker> unpacker_; scoped_refptr<SandboxedExtensionUnpacker> sandboxed_unpacker_; @@ -135,6 +165,8 @@ TEST_F(SandboxedExtensionUnpackerTest, NoCatalogsSuccess) { // Check that there still is no _locales folder. EXPECT_FALSE(file_util::PathExists(install_path)); + + ASSERT_TRUE(TempFilesRemoved()); } TEST_F(SandboxedExtensionUnpackerTest, WithCatalogsSuccess) { @@ -164,4 +196,6 @@ TEST_F(SandboxedExtensionUnpackerTest, WithCatalogsSuccess) { EXPECT_TRUE(file_util::GetFileInfo(messages_file, &new_info)); EXPECT_TRUE(new_info.last_modified > old_info.last_modified); + + ASSERT_TRUE(TempFilesRemoved()); } diff --git a/chrome/common/chrome_paths.cc b/chrome/common/chrome_paths.cc index eccb65b..aefcebc 100644 --- a/chrome/common/chrome_paths.cc +++ b/chrome/common/chrome_paths.cc @@ -186,6 +186,12 @@ bool PathProvider(int key, FilePath* result) { cur = cur.Append(FILE_PATH_LITERAL("Dictionaries")); create_dir = true; break; + case chrome::DIR_USER_DATA_TEMP: + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("Temp")); + create_dir = true; + break; case chrome::FILE_LOCAL_STATE: if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) return false; diff --git a/chrome/common/chrome_paths.h b/chrome/common/chrome_paths.h index c5e13d2..9ed8057 100644 --- a/chrome/common/chrome_paths.h +++ b/chrome/common/chrome_paths.h @@ -32,6 +32,10 @@ enum { DIR_DEFAULT_DOWNLOADS_SAFE, // Directory for a user's // "My Documents/Downloads". DIR_DEFAULT_DOWNLOADS, // Directory for a user's downloads. + DIR_USER_DATA_TEMP, // A temp directory within DIR_USER_DATA. Use + // this when a temporary file or directory will + // be moved into the profile, to avoid issues + // moving across volumes. See crbug.com/13044 . FILE_RESOURCE_MODULE, // Full path and filename of the module that // contains embedded resources (version, // strings, images, etc.). diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc index 1db05cb..174701c 100644 --- a/chrome/common/extensions/extension_constants.cc +++ b/chrome/common/extensions/extension_constants.cc @@ -253,3 +253,14 @@ const char* kGalleryDownloadPrefix = const char* kMiniGalleryBrowsePrefix = "https://tools.google.com/chrome/"; const char* kMiniGalleryDownloadPrefix = "https://dl-ssl.google.com/chrome/"; } + +namespace extension_filenames { +const char* kTempExtensionName = "CRX_INSTALL"; + +// The file to write our decoded images to, relative to the extension_path. +const char* kDecodedImagesFilename = "DECODED_IMAGES"; + +// The file to write our decoded message catalogs to, relative to the +// extension_path. +const char* kDecodedMessageCatalogsFilename = "DECODED_MESSAGE_CATALOGS"; +} diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h index 1b1e798..36ba762 100644 --- a/chrome/common/extensions/extension_constants.h +++ b/chrome/common/extensions/extension_constants.h @@ -175,4 +175,17 @@ namespace extension_urls { extern const char* kMiniGalleryDownloadPrefix; } // namespace extension_urls +namespace extension_filenames { + // The name of a temporary directory to install an extension into for + // validation before finalizing install. + extern const char* kTempExtensionName; + + // The file to write our decoded images to, relative to the extension_path. + extern const char* kDecodedImagesFilename; + + // The file to write our decoded message catalogs to, relative to the + // extension_path. + extern const char* kDecodedMessageCatalogsFilename; +} + #endif // CHROME_COMMON_EXTENSIONS_EXTENSION_CONSTANTS_H_ diff --git a/chrome/common/extensions/extension_file_util.h b/chrome/common/extensions/extension_file_util.h index b711df0..dc6a5bd 100644 --- a/chrome/common/extensions/extension_file_util.h +++ b/chrome/common/extensions/extension_file_util.h @@ -25,7 +25,7 @@ extern const char kInstallDirectoryName[]; extern const char kCurrentVersionFileName[]; // Move source_dir to dest_dir (it will actually be named dest_dir, not inside -// dest_dir). If the parent path doesn't exixt, create it. If something else is +// dest_dir). If the parent path doesn't exist, create it. If something else is // already there, remove it. bool MoveDirSafely(const FilePath& source_dir, const FilePath& dest_dir); diff --git a/chrome/common/extensions/extension_unpacker.cc b/chrome/common/extensions/extension_unpacker.cc index dad10f4..8c634e2 100644 --- a/chrome/common/extensions/extension_unpacker.cc +++ b/chrome/common/extensions/extension_unpacker.cc @@ -26,18 +26,9 @@ namespace errors = extension_manifest_errors; namespace keys = extension_manifest_keys; +namespace filenames = extension_filenames; namespace { -// The name of a temporary directory to install an extension into for -// validation before finalizing install. -const char kTempExtensionName[] = "TEMP_INSTALL"; - -// The file to write our decoded images to, relative to the extension_path. -const char kDecodedImagesFilename[] = "DECODED_IMAGES"; - -// The file to write our decoded message catalogs to, relative to the -// extension_path. -const char kDecodedMessageCatalogsFilename[] = "DECODED_MESSAGE_CATALOGS"; // Errors const char* kCouldNotCreateDirectoryError = @@ -148,7 +139,7 @@ bool ExtensionUnpacker::Run() { // <profile>/Extensions/INSTALL_TEMP/<version> temp_install_dir_ = - extension_path_.DirName().AppendASCII(kTempExtensionName); + extension_path_.DirName().AppendASCII(filenames::kTempExtensionName); if (!file_util::CreateDirectory(temp_install_dir_)) { #if defined(OS_WIN) std::string dir_string = WideToUTF8(temp_install_dir_.value()); @@ -209,7 +200,8 @@ bool ExtensionUnpacker::DumpImagesToFile() { IPC::Message pickle; // We use a Message so we can use WriteParam. IPC::WriteParam(&pickle, decoded_images_); - FilePath path = extension_path_.DirName().AppendASCII(kDecodedImagesFilename); + FilePath path = extension_path_.DirName().AppendASCII( + filenames::kDecodedImagesFilename); if (!file_util::WriteFile(path, static_cast<const char*>(pickle.data()), pickle.size())) { SetError("Could not write image data to disk."); @@ -224,7 +216,7 @@ bool ExtensionUnpacker::DumpMessageCatalogsToFile() { IPC::WriteParam(&pickle, *parsed_catalogs_.get()); FilePath path = extension_path_.DirName().AppendASCII( - kDecodedMessageCatalogsFilename); + filenames::kDecodedMessageCatalogsFilename); if (!file_util::WriteFile(path, static_cast<const char*>(pickle.data()), pickle.size())) { SetError("Could not write message catalogs to disk."); @@ -237,7 +229,7 @@ bool ExtensionUnpacker::DumpMessageCatalogsToFile() { // static bool ExtensionUnpacker::ReadImagesFromFile(const FilePath& extension_path, DecodedImages* images) { - FilePath path = extension_path.AppendASCII(kDecodedImagesFilename); + FilePath path = extension_path.AppendASCII(filenames::kDecodedImagesFilename); std::string file_str; if (!file_util::ReadFileToString(path, &file_str)) return false; @@ -250,7 +242,8 @@ bool ExtensionUnpacker::ReadImagesFromFile(const FilePath& extension_path, // static bool ExtensionUnpacker::ReadMessageCatalogsFromFile( const FilePath& extension_path, DictionaryValue* catalogs) { - FilePath path = extension_path.AppendASCII(kDecodedMessageCatalogsFilename); + FilePath path = extension_path.AppendASCII( + filenames::kDecodedMessageCatalogsFilename); std::string file_str; if (!file_util::ReadFileToString(path, &file_str)) return false; |