fix: access of out-of-scope reference in ShowOpenDialog and ShowSaveDialog (#17126)

In the mac file dialog implementation of show*OpenDialog, a settings
object is passed down to the dialog completion handler.
However at the time the completion handler is invoked, the settings
object is already out-of-scope, resulting in an invalid access to
the security_scoped_bookmarks flag.
The fix is to capture the value of the flag and passing that directly
to the completion handler.

fixes issue #16664
This commit is contained in:
Johann Fuechsl 2019-02-27 09:14:04 +01:00 коммит произвёл Shelley Vohr
Родитель 5a99ea4c46
Коммит 42aa375497
1 изменённых файлов: 14 добавлений и 8 удалений

Просмотреть файл

@ -286,7 +286,7 @@ bool ShowOpenDialog(const DialogSettings& settings,
void OpenDialogCompletion(int chosen,
NSOpenPanel* dialog,
const DialogSettings& settings,
bool security_scoped_bookmarks,
const OpenDialogCallback& callback) {
if (chosen == NSFileHandlingPanelCancelButton) {
#if defined(MAS_BUILD)
@ -299,7 +299,7 @@ void OpenDialogCompletion(int chosen,
std::vector<base::FilePath> paths;
#if defined(MAS_BUILD)
std::vector<std::string> bookmarks;
if (settings.security_scoped_bookmarks) {
if (security_scoped_bookmarks) {
ReadDialogPathsWithBookmarks(dialog, &paths, &bookmarks);
} else {
ReadDialogPaths(dialog, &paths);
@ -322,18 +322,22 @@ void ShowOpenDialog(const DialogSettings& settings,
// Duplicate the callback object here since c is a reference and gcd would
// only store the pointer, by duplication we can force gcd to store a copy.
__block OpenDialogCallback callback = c;
// Capture the value of the security_scoped_bookmarks settings flag
// and pass it to the completion handler.
bool security_scoped_bookmarks = settings.security_scoped_bookmarks;
if (!settings.parent_window || !settings.parent_window->GetNativeWindow() ||
settings.force_detached) {
[dialog beginWithCompletionHandler:^(NSInteger chosen) {
OpenDialogCompletion(chosen, dialog, settings, callback);
OpenDialogCompletion(chosen, dialog, security_scoped_bookmarks, callback);
}];
} else {
NSWindow* window =
settings.parent_window->GetNativeWindow().GetNativeNSWindow();
[dialog beginSheetModalForWindow:window
completionHandler:^(NSInteger chosen) {
OpenDialogCompletion(chosen, dialog, settings, callback);
OpenDialogCompletion(chosen, dialog,
security_scoped_bookmarks, callback);
}];
}
}
@ -354,7 +358,7 @@ bool ShowSaveDialog(const DialogSettings& settings, base::FilePath* path) {
void SaveDialogCompletion(int chosen,
NSSavePanel* dialog,
const DialogSettings& settings,
bool security_scoped_bookmarks,
const SaveDialogCallback& callback) {
if (chosen == NSFileHandlingPanelCancelButton) {
#if defined(MAS_BUILD)
@ -366,7 +370,7 @@ void SaveDialogCompletion(int chosen,
std::string path = base::SysNSStringToUTF8([[dialog URL] path]);
#if defined(MAS_BUILD)
std::string bookmark;
if (settings.security_scoped_bookmarks) {
if (security_scoped_bookmarks) {
bookmark = GetBookmarkDataFromNSURL([dialog URL]);
}
callback.Run(true, base::FilePath(path), bookmark);
@ -384,18 +388,20 @@ void ShowSaveDialog(const DialogSettings& settings,
[dialog setCanSelectHiddenExtension:YES];
__block SaveDialogCallback callback = c;
bool security_scoped_bookmarks = settings.security_scoped_bookmarks;
if (!settings.parent_window || !settings.parent_window->GetNativeWindow() ||
settings.force_detached) {
[dialog beginWithCompletionHandler:^(NSInteger chosen) {
SaveDialogCompletion(chosen, dialog, settings, callback);
SaveDialogCompletion(chosen, dialog, security_scoped_bookmarks, callback);
}];
} else {
NSWindow* window =
settings.parent_window->GetNativeWindow().GetNativeNSWindow();
[dialog beginSheetModalForWindow:window
completionHandler:^(NSInteger chosen) {
SaveDialogCompletion(chosen, dialog, settings, callback);
SaveDialogCompletion(chosen, dialog,
security_scoped_bookmarks, callback);
}];
}
}