From 1aae1c11e3db5f2fb96f1741a54eada08669a0db Mon Sep 17 00:00:00 2001 From: "trop[bot]" Date: Fri, 1 Mar 2019 08:19:03 +0000 Subject: [PATCH] fix: access of out-of-scope reference in ShowOpenDialog and ShowSaveDialog (#17177) 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 --- atom/browser/ui/file_dialog_mac.mm | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/atom/browser/ui/file_dialog_mac.mm b/atom/browser/ui/file_dialog_mac.mm index 5248441fe7f76..e2cfd96fa6e28 100644 --- a/atom/browser/ui/file_dialog_mac.mm +++ b/atom/browser/ui/file_dialog_mac.mm @@ -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 paths; #if defined(MAS_BUILD) std::vector 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); }]; } }