diff options
-rw-r--r-- | base/file_path.cc | 12 | ||||
-rw-r--r-- | base/file_path.h | 4 | ||||
-rw-r--r-- | base/file_path_unittest.cc | 83 | ||||
-rw-r--r-- | chrome/browser/download/download_manager.cc | 27 | ||||
-rw-r--r-- | chrome/common/extensions/extension.cc | 8 | ||||
-rw-r--r-- | chrome/common/extensions/extension.h | 3 |
6 files changed, 89 insertions, 48 deletions
diff --git a/base/file_path.cc b/base/file_path.cc index e3dfbbd..6712d70 100644 --- a/base/file_path.cc +++ b/base/file_path.cc @@ -284,6 +284,18 @@ FilePath FilePath::ReplaceExtension(const StringType& extension) const { return FilePath(str); } +bool FilePath::MatchesExtension(const StringType& extension) const { + FilePath::StringType current_extension = Extension(); + + if (current_extension.length() != extension.length()) + return false; + + return std::equal(extension.begin(), + extension.end(), + current_extension.begin(), + CaseInsensitiveCompare<FilePath::CharType>()); +} + FilePath FilePath::Append(const StringType& component) const { DCHECK(!IsPathAbsolute(component)); if (path_.compare(kCurrentDirectory) == 0) { diff --git a/base/file_path.h b/base/file_path.h index ae4d36d..5fe8cda 100644 --- a/base/file_path.h +++ b/base/file_path.h @@ -197,6 +197,10 @@ class FilePath { // Returns "" if BaseName() == "." or "..". FilePath ReplaceExtension(const StringType& extension) const; + // Returns true if the file path matches the specified extension. The test is + // case insensitive. Don't forget the leading period if appropriate. + bool MatchesExtension(const StringType& extension) const; + // Returns a FilePath by appending a separator and the supplied path // component to this object's path. Append takes care to avoid adding // excessive separators if this object's path already ends with a separator. diff --git a/base/file_path_unittest.cc b/base/file_path_unittest.cc index 0df6838..55efeac 100644 --- a/base/file_path_unittest.cc +++ b/base/file_path_unittest.cc @@ -435,35 +435,35 @@ TEST_F(FilePathTest, PathComponentsTest) { TEST_F(FilePathTest, IsParentTest) { const struct BinaryBooleanTestData cases[] = { - { { FPL("/"), FPL("/foo/bar/baz") }, true}, - { { FPL("/foo/bar"), FPL("/foo/bar/baz") }, true}, - { { FPL("/foo/bar/"), FPL("/foo/bar/baz") }, true}, - { { FPL("//foo/bar/"), FPL("//foo/bar/baz") }, true}, - { { FPL("/foo/bar"), FPL("/foo2/bar/baz") }, false}, - { { FPL("/foo/bar.txt"), FPL("/foo/bar/baz") }, false}, - { { FPL("/foo/bar"), FPL("/foo/bar2/baz") }, false}, - { { FPL("/foo/bar"), FPL("/foo/bar") }, false}, - { { FPL("/foo/bar/baz"), FPL("/foo/bar") }, false}, - { { FPL("foo/bar"), FPL("foo/bar/baz") }, true}, - { { FPL("foo/bar"), FPL("foo2/bar/baz") }, false}, - { { FPL("foo/bar"), FPL("foo/bar2/baz") }, false}, - { { FPL(""), FPL("foo") }, false}, + { { FPL("/"), FPL("/foo/bar/baz") }, true}, + { { FPL("/foo/bar"), FPL("/foo/bar/baz") }, true}, + { { FPL("/foo/bar/"), FPL("/foo/bar/baz") }, true}, + { { FPL("//foo/bar/"), FPL("//foo/bar/baz") }, true}, + { { FPL("/foo/bar"), FPL("/foo2/bar/baz") }, false}, + { { FPL("/foo/bar.txt"), FPL("/foo/bar/baz") }, false}, + { { FPL("/foo/bar"), FPL("/foo/bar2/baz") }, false}, + { { FPL("/foo/bar"), FPL("/foo/bar") }, false}, + { { FPL("/foo/bar/baz"), FPL("/foo/bar") }, false}, + { { FPL("foo/bar"), FPL("foo/bar/baz") }, true}, + { { FPL("foo/bar"), FPL("foo2/bar/baz") }, false}, + { { FPL("foo/bar"), FPL("foo/bar2/baz") }, false}, + { { FPL(""), FPL("foo") }, false}, #if defined(FILE_PATH_USES_DRIVE_LETTERS) - { { FPL("c:/foo/bar"), FPL("c:/foo/bar/baz") }, true}, - { { FPL("c:/"), FPL("c:/foo/bar/baz") }, true}, - { { FPL("c:"), FPL("c:/foo/bar/baz") }, true}, - { { FPL("c:/foo/bar"), FPL("d:/foo/bar/baz") }, false}, - { { FPL("c:/foo/bar"), FPL("c:/foo2/bar/baz") }, false}, - { { FPL("c:/foo/bar"), FPL("c:/foo/bar2/baz") }, false}, + { { FPL("c:/foo/bar"), FPL("c:/foo/bar/baz") }, true}, + { { FPL("c:/"), FPL("c:/foo/bar/baz") }, true}, + { { FPL("c:"), FPL("c:/foo/bar/baz") }, true}, + { { FPL("c:/foo/bar"), FPL("d:/foo/bar/baz") }, false}, + { { FPL("c:/foo/bar"), FPL("c:/foo2/bar/baz") }, false}, + { { FPL("c:/foo/bar"), FPL("c:/foo/bar2/baz") }, false}, #endif // FILE_PATH_USES_DRIVE_LETTERS #if defined(FILE_PATH_USES_WIN_SEPARATORS) - { { FPL("\\foo\\bar"), FPL("\\foo\\bar\\baz") }, true}, - { { FPL("\\foo/bar"), FPL("\\foo\\bar\\baz") }, true}, - { { FPL("\\foo/bar"), FPL("\\foo/bar/baz") }, true}, - { { FPL("\\"), FPL("\\foo\\bar\\baz") }, true}, - { { FPL(""), FPL("\\foo\\bar\\baz") }, false}, - { { FPL("\\foo\\bar"), FPL("\\foo2\\bar\\baz") }, false}, - { { FPL("\\foo\\bar"), FPL("\\foo\\bar2\\baz") }, false}, + { { FPL("\\foo\\bar"), FPL("\\foo\\bar\\baz") }, true}, + { { FPL("\\foo/bar"), FPL("\\foo\\bar\\baz") }, true}, + { { FPL("\\foo/bar"), FPL("\\foo/bar/baz") }, true}, + { { FPL("\\"), FPL("\\foo\\bar\\baz") }, true}, + { { FPL(""), FPL("\\foo\\bar\\baz") }, false}, + { { FPL("\\foo\\bar"), FPL("\\foo2\\bar\\baz") }, false}, + { { FPL("\\foo\\bar"), FPL("\\foo\\bar2\\baz") }, false}, #endif // FILE_PATH_USES_DRIVE_LETTERS }; @@ -634,3 +634,34 @@ TEST_F(FilePathTest, ReplaceExtension) { ", path: " << path.value() << ", replace: " << cases[i].inputs[1]; } } + +TEST_F(FilePathTest, MatchesExtension) { + const struct BinaryBooleanTestData cases[] = { + { { FPL("foo"), FPL("") }, true}, + { { FPL("foo"), FPL(".") }, false}, + { { FPL("foo."), FPL("") }, false}, + { { FPL("foo."), FPL(".") }, true}, + { { FPL("foo.txt"), FPL(".dll") }, false}, + { { FPL("foo.txt"), FPL(".txt") }, true}, + { { FPL("foo.txt.dll"), FPL(".txt") }, false}, + { { FPL("foo.txt.dll"), FPL(".dll") }, true}, +#if defined(FILE_PATH_USES_DRIVE_LETTERS) + { { FPL("c:/foo.txt.dll"), FPL(".txt") }, false}, + { { FPL("c:/foo.txt"), FPL(".txt") }, true}, +#endif // FILE_PATH_USES_DRIVE_LETTERS +#if defined(FILE_PATH_USES_WIN_SEPARATORS) + { { FPL("c:\\bar\\foo.txt.dll"), FPL(".txt") }, false}, + { { FPL("c:\\bar\\foo.txt"), FPL(".txt") }, true}, +#endif // FILE_PATH_USES_DRIVE_LETTERS + { { FPL("/bar/foo.txt.dll"), FPL(".txt") }, false}, + { { FPL("/bar/foo.txt"), FPL(".txt") }, true}, + }; + + for (size_t i = 0; i < arraysize(cases); ++i) { + FilePath path(cases[i].inputs[0]); + FilePath::StringType ext(cases[i].inputs[1]); + + EXPECT_EQ(cases[i].expected, path.MatchesExtension(ext)) << + "i: " << i << ", path: " << path.value() << ", ext: " << ext; + } +} diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc index 7ed4ad0..bd74f91 100644 --- a/chrome/browser/download/download_manager.cc +++ b/chrome/browser/download/download_manager.cc @@ -26,7 +26,6 @@ #include "chrome/browser/renderer_host/resource_dispatcher_host.h" #include "chrome/browser/tab_contents/tab_util.h" #include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/platform_util.h" @@ -826,14 +825,8 @@ void DownloadManager::DownloadFinished(int32 download_id, int64 size) { void DownloadManager::DownloadRenamedToFinalName(int download_id, const FilePath& full_path) { - FilePath::StringType extension = full_path.Extension(); - // Drop the leading period. - if (extension.size() > 0) - extension = extension.substr(1); - - if (extension == chrome::kExtensionFileExtension) { + if (Extension::IsExtension(full_path)) OpenChromeExtension(full_path); - } } void DownloadManager::ContinueDownloadFinished(DownloadItem* download) { @@ -849,12 +842,9 @@ void DownloadManager::ContinueDownloadFinished(DownloadItem* download) { // Open the download if the user or user prefs indicate it should be. FilePath::StringType extension = download->full_path().Extension(); - // Drop the leading period. - if (extension.size() > 0) - extension = extension.substr(1); // Handle chrome extensions explicitly and skip the shell execute. - if (extension == chrome::kExtensionFileExtension) { + if (Extension::IsExtension(download->full_path())) { // Skip the shell execute. This will be handled in // DownloadRenamedToFinalName return; @@ -1218,14 +1208,9 @@ void DownloadManager::ShowDownloadInShell(const DownloadItem* download) { void DownloadManager::OpenDownload(const DownloadItem* download, gfx::NativeView parent_window) { - FilePath::StringType extension = download->full_path().Extension(); - // Drop the leading period. - if (extension.size() > 0) - extension = extension.substr(1); - // Open Chrome extensions with ExtensionsService. For everything else do shell // execute. - if (extension == chrome::kExtensionFileExtension) { + if (Extension::IsExtension(download->full_path())) { OpenChromeExtension(download->full_path()); } else { OpenDownloadInShell(download, parent_window); @@ -1260,7 +1245,7 @@ bool DownloadManager::ShouldOpenFileExtension( // Special-case Chrome extensions as always-open. if (!IsExecutable(extension) && (auto_open_.find(extension) != auto_open_.end() || - extension == chrome::kExtensionFileExtension)) + Extension::IsExtension(FilePath(extension)))) return true; return false; } @@ -1484,9 +1469,7 @@ void DownloadManager::ShowDownloadInBrowser(const DownloadCreateInfo& info, // Extension downloading skips the shelf. This is a temporary fix until // we can modularize the download system and develop specific extensiona // install UI. - FilePath::StringType extension = info.path.Extension(); - // Ignore the leading period. - if (extension.find(chrome::kExtensionFileExtension) == 1) + if (Extension::IsExtension(info.path)) return; // The 'contents' may no longer exist if the user closed the tab before we get diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc index 9b74737..33baff8 100644 --- a/chrome/common/extensions/extension.cc +++ b/chrome/common/extensions/extension.cc @@ -12,6 +12,7 @@ #include "base/string_util.h" #include "base/third_party/nss/blapi.h" #include "base/third_party/nss/sha256.h" +#include "chrome/common/chrome_constants.h" #include "chrome/common/extensions/extension_error_reporter.h" #include "chrome/common/extensions/extension_error_utils.h" #include "chrome/common/extensions/user_script.h" @@ -199,6 +200,13 @@ const std::string Extension::VersionString() const { } // static +bool Extension::IsExtension(const FilePath& file_name) { + return file_name.MatchesExtension( + FilePath::StringType(FILE_PATH_LITERAL(".")) + + chrome::kExtensionFileExtension); +} + +// static bool Extension::IdIsValid(const std::string& id) { // Verify that the id is legal. if (id.size() != (kIdSize * 2)) diff --git a/chrome/common/extensions/extension.h b/chrome/common/extensions/extension.h index 1b774ae..ec14b0b 100644 --- a/chrome/common/extensions/extension.h +++ b/chrome/common/extensions/extension.h @@ -142,6 +142,9 @@ class Extension { explicit Extension(const FilePath& path); virtual ~Extension(); + // Returns true if the specified file is an extension. + static bool IsExtension(const FilePath& file_name); + // Resets the id counter. This is only useful for unit tests. static void ResetGeneratedIdCounter() { id_counter_ = 0; |