Browse Source

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
trop[bot] 6 years ago
parent
commit
1aae1c11e3
1 changed files with 14 additions and 8 deletions
  1. 14 8
      atom/browser/ui/file_dialog_mac.mm

+ 14 - 8
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<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);
                    }];
   }
 }