summaryrefslogtreecommitdiffstats
path: root/ui/base/win
diff options
context:
space:
mode:
authorerikwright@chromium.org <erikwright@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-14 17:14:50 +0000
committererikwright@chromium.org <erikwright@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-14 17:16:37 +0000
commit85807e83cc6022df06bda61d5bf32032a1837ac1 (patch)
tree3e1f5c5a916af11a7fcb017d1e1912e9c5b9d636 /ui/base/win
parent5614f28582b0665d79218fb00f014d4afad4576d (diff)
downloadchromium_src-85807e83cc6022df06bda61d5bf32032a1837ac1.zip
chromium_src-85807e83cc6022df06bda61d5bf32032a1837ac1.tar.gz
chromium_src-85807e83cc6022df06bda61d5bf32032a1837ac1.tar.bz2
Experimentally isolate GetOpenFileName in a utility process.
GetOpenFileName can cause 3rd-party shell extensions to be loaded into the caller's process. By putting it in a separate process we protect the browser process from potential instability. BUG=73098 Review URL: https://codereview.chromium.org/419523006 Cr-Commit-Position: refs/heads/master@{#289625} git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289625 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/base/win')
-rw-r--r--ui/base/win/open_file_name_win.cc72
-rw-r--r--ui/base/win/open_file_name_win.h19
-rw-r--r--ui/base/win/open_file_name_win_unittest.cc119
3 files changed, 200 insertions, 10 deletions
diff --git a/ui/base/win/open_file_name_win.cc b/ui/base/win/open_file_name_win.cc
index 2d67b1f..b63eb47 100644
--- a/ui/base/win/open_file_name_win.cc
+++ b/ui/base/win/open_file_name_win.cc
@@ -27,6 +27,25 @@ OpenFileName::OpenFileName(HWND parent_window, DWORD flags) {
OpenFileName::~OpenFileName() {
}
+void OpenFileName::SetFilters(
+ const std::vector<Tuple2<base::string16, base::string16> >& filters) {
+ openfilename_.lpstrFilter = NULL;
+ filter_buffer_.clear();
+ if (filters.empty())
+ return;
+ for (std::vector<Tuple2<base::string16, base::string16> >::const_iterator
+ it = filters.begin();
+ it != filters.end();
+ ++it) {
+ filter_buffer_.append(it->a);
+ filter_buffer_.push_back(0);
+ filter_buffer_.append(it->b);
+ filter_buffer_.push_back(0);
+ }
+ filter_buffer_.push_back(0);
+ openfilename_.lpstrFilter = filter_buffer_.c_str();
+}
+
void OpenFileName::SetInitialSelection(const base::FilePath& initial_directory,
const base::FilePath& initial_filename) {
// First reset to the default case.
@@ -83,5 +102,58 @@ void OpenFileName::GetResult(base::FilePath* directory,
}
}
+// static
+void OpenFileName::SetResult(const base::FilePath& directory,
+ const std::vector<base::FilePath>& filenames,
+ OPENFILENAME* openfilename) {
+ base::string16 filename_value;
+ if (filenames.size() == 1) {
+ filename_value = directory.Append(filenames[0]).value();
+ } else {
+ filename_value = directory.value();
+ filename_value.push_back(0);
+ for (std::vector<base::FilePath>::const_iterator it = filenames.begin();
+ it != filenames.end();
+ ++it) {
+ filename_value.append(it->value());
+ filename_value.push_back(0);
+ }
+ }
+ if (filename_value.size() + 1 < openfilename->nMaxFile) {
+ // Because the result has embedded nulls, we must memcpy.
+ memcpy(openfilename->lpstrFile,
+ filename_value.c_str(),
+ (filename_value.size() + 1) * sizeof(filename_value[0]));
+ } else if (openfilename->nMaxFile) {
+ openfilename->lpstrFile[0] = 0;
+ }
+}
+
+// static
+std::vector<Tuple2<base::string16, base::string16> > OpenFileName::GetFilters(
+ const OPENFILENAME* openfilename) {
+ std::vector<Tuple2<base::string16, base::string16> > filters;
+
+ const base::char16* display_string = openfilename->lpstrFilter;
+ if (!display_string)
+ return filters;
+
+ while (*display_string) {
+ const base::char16* display_string_end = display_string;
+ while (*display_string_end)
+ ++display_string_end;
+ const base::char16* pattern = display_string_end + 1;
+ const base::char16* pattern_end = pattern;
+ while (*pattern_end)
+ ++pattern_end;
+ filters.push_back(
+ MakeTuple(base::string16(display_string, display_string_end),
+ base::string16(pattern, pattern_end)));
+ display_string = pattern_end + 1;
+ }
+
+ return filters;
+}
+
} // namespace win
} // namespace ui
diff --git a/ui/base/win/open_file_name_win.h b/ui/base/win/open_file_name_win.h
index 4787c83..79a7185 100644
--- a/ui/base/win/open_file_name_win.h
+++ b/ui/base/win/open_file_name_win.h
@@ -32,6 +32,10 @@ class UI_BASE_EXPORT OpenFileName {
OpenFileName(HWND parent_window, DWORD flags);
~OpenFileName();
+ // Initializes |lpstrFilter| from the label/pattern pairs in |filters|.
+ void SetFilters(
+ const std::vector<Tuple2<base::string16, base::string16> >& filters);
+
// Sets |lpstrInitialDir| and |lpstrFile|.
void SetInitialSelection(const base::FilePath& initial_directory,
const base::FilePath& initial_filename);
@@ -47,10 +51,25 @@ class UI_BASE_EXPORT OpenFileName {
// Returns the OPENFILENAME structure.
OPENFILENAME* GetOPENFILENAME() { return &openfilename_; }
+ // Returns the OPENFILENAME structure.
+ const OPENFILENAME* GetOPENFILENAME() const { return &openfilename_; }
+
+ // Stores directory and filenames in the buffer pointed to by
+ // |openfilename->lpstrFile| and sized |openfilename->nMaxFile|.
+ static void SetResult(const base::FilePath& directory,
+ const std::vector<base::FilePath>& filenames,
+ OPENFILENAME* openfilename);
+
+ // Returns a vector of label/pattern pairs built from
+ // |openfilename->lpstrFilter|.
+ static std::vector<Tuple2<base::string16, base::string16> > GetFilters(
+ const OPENFILENAME* openfilename);
+
private:
OPENFILENAME openfilename_;
base::string16 initial_directory_buffer_;
wchar_t filename_buffer_[UNICODE_STRING_MAX_CHARS];
+ base::string16 filter_buffer_;
DISALLOW_COPY_AND_ASSIGN(OpenFileName);
};
diff --git a/ui/base/win/open_file_name_win_unittest.cc b/ui/base/win/open_file_name_win_unittest.cc
index a38e4d6..f69ec97 100644
--- a/ui/base/win/open_file_name_win_unittest.cc
+++ b/ui/base/win/open_file_name_win_unittest.cc
@@ -12,16 +12,64 @@ const HWND kHwnd = reinterpret_cast<HWND>(0xDEADBEEF);
const DWORD kFlags = OFN_OVERWRITEPROMPT | OFN_EXPLORER | OFN_ENABLESIZING;
void SetResult(const base::string16& result, ui::win::OpenFileName* ofn) {
- EXPECT_GT(ofn->GetOPENFILENAME()->nMaxFile, result.size());
- if (ofn->GetOPENFILENAME()->nMaxFile > result.size()) {
- if (!result.size()) {
- ofn->GetOPENFILENAME()->lpstrFile[0] = 0;
- } else {
- // Because the result has embedded nulls, we must memcpy.
- memcpy(ofn->GetOPENFILENAME()->lpstrFile,
- result.c_str(),
- (result.size() + 1) * sizeof(result[0]));
- }
+ if (ofn->GetOPENFILENAME()->nMaxFile <= result.size()) {
+ ADD_FAILURE() << "filename buffer insufficient.";
+ return;
+ }
+ if (!result.size()) {
+ ofn->GetOPENFILENAME()->lpstrFile[0] = 0;
+ } else {
+ // Because the result has embedded nulls, we must memcpy.
+ memcpy(ofn->GetOPENFILENAME()->lpstrFile,
+ result.c_str(),
+ (result.size() + 1) * sizeof(result[0]));
+ }
+}
+
+void CheckFilters(
+ const std::vector<Tuple2<base::string16, base::string16> >& expected,
+ const std::vector<Tuple2<base::string16, base::string16> >& actual) {
+ if (expected.size() != actual.size()) {
+ ADD_FAILURE() << "filter count mismatch. Got " << actual.size()
+ << " expected " << expected.size() << ".";
+ return;
+ }
+
+ for (size_t i = 0; i < expected.size(); ++i) {
+ EXPECT_EQ(expected[i].a, actual[i].a) << "Mismatch at index " << i;
+ EXPECT_EQ(expected[i].b, actual[i].b) << "Mismatch at index " << i;
+ }
+}
+
+void CheckFilterString(const base::string16& expected,
+ const ui::win::OpenFileName& ofn) {
+ if (!ofn.GetOPENFILENAME()->lpstrFilter) {
+ ADD_FAILURE() << "Filter string is NULL.";
+ return;
+ }
+ if (expected.size() == 0) {
+ EXPECT_EQ(0, ofn.GetOPENFILENAME()->lpstrFilter[0]);
+ } else {
+ EXPECT_EQ(0,
+ memcmp(expected.c_str(),
+ ofn.GetOPENFILENAME()->lpstrFilter,
+ expected.size() + 1 * sizeof(expected[0])));
+ }
+}
+
+void CheckResult(const base::string16& expected,
+ const ui::win::OpenFileName& ofn) {
+ if (!ofn.GetOPENFILENAME()->lpstrFile) {
+ ADD_FAILURE() << "File string is NULL.";
+ return;
+ }
+ if (expected.size() == 0) {
+ EXPECT_EQ(0, ofn.GetOPENFILENAME()->lpstrFile[0]);
+ } else {
+ EXPECT_EQ(0,
+ memcmp(expected.c_str(),
+ ofn.GetOPENFILENAME()->lpstrFile,
+ expected.size() + 1 * sizeof(expected[0])));
}
}
@@ -135,3 +183,54 @@ TEST(OpenFileNameTest, GetResult) {
EXPECT_EQ(base::FilePath(), directory);
ASSERT_EQ(0u, filenames.size());
}
+
+TEST(OpenFileNameTest, SetAndGetFilters) {
+ const base::string16 kNull(L"\0", 1);
+
+ ui::win::OpenFileName ofn(kHwnd, kFlags);
+ std::vector<Tuple2<base::string16, base::string16> > filters;
+ ofn.SetFilters(filters);
+ EXPECT_FALSE(ofn.GetOPENFILENAME()->lpstrFilter);
+ CheckFilters(filters,
+ ui::win::OpenFileName::GetFilters(ofn.GetOPENFILENAME()));
+
+ filters.push_back(MakeTuple(base::string16(L"a"), base::string16(L"b")));
+ ofn.SetFilters(filters);
+ CheckFilterString(L"a" + kNull + L"b" + kNull, ofn);
+ CheckFilters(filters,
+ ui::win::OpenFileName::GetFilters(ofn.GetOPENFILENAME()));
+
+ filters.push_back(MakeTuple(base::string16(L"X"), base::string16(L"Y")));
+ ofn.SetFilters(filters);
+ CheckFilterString(L"a" + kNull + L"b" + kNull + L"X" + kNull + L"Y" + kNull,
+ ofn);
+ CheckFilters(filters,
+ ui::win::OpenFileName::GetFilters(ofn.GetOPENFILENAME()));
+}
+
+TEST(OpenFileNameTest, SetResult) {
+ const base::string16 kNull(L"\0", 1);
+
+ ui::win::OpenFileName ofn(kHwnd, kFlags);
+ base::FilePath directory;
+ std::vector<base::FilePath> filenames;
+
+ ui::win::OpenFileName::SetResult(directory, filenames, ofn.GetOPENFILENAME());
+ CheckResult(L"", ofn);
+
+ directory = base::FilePath(L"C:\\dir");
+ filenames.push_back(base::FilePath(L"file"));
+ ui::win::OpenFileName::SetResult(directory, filenames, ofn.GetOPENFILENAME());
+ CheckResult(L"C:\\dir\\file" + kNull, ofn);
+
+ filenames.push_back(base::FilePath(L"otherfile"));
+ ui::win::OpenFileName::SetResult(directory, filenames, ofn.GetOPENFILENAME());
+ CheckResult(L"C:\\dir" + kNull + L"file" + kNull + L"otherfile" + kNull, ofn);
+
+ base::char16 short_buffer[10] = L"";
+
+ ofn.GetOPENFILENAME()->lpstrFile = short_buffer;
+ ofn.GetOPENFILENAME()->nMaxFile = arraysize(short_buffer);
+ ui::win::OpenFileName::SetResult(directory, filenames, ofn.GetOPENFILENAME());
+ CheckResult(L"", ofn);
+}