summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/file_path.cc12
-rw-r--r--base/file_path.h4
-rw-r--r--base/file_path_unittest.cc83
-rw-r--r--chrome/browser/download/download_manager.cc27
-rw-r--r--chrome/common/extensions/extension.cc8
-rw-r--r--chrome/common/extensions/extension.h3
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;