Ver Fonte

Bug 2036: Crash when new contents is copied to the clipboard while downloading files pasted from the clipboard

https://winscp.net/tracker/2036
(cherry picked from commit b532a8c0d13537750a03afb0b52578bcbc79b2ea)

# Conflicts:
#	source/forms/CustomScpExplorer.cpp

Source commit: 943d41bad2fee74b3fbb48019d43e4139f9b49c0
Martin Prikryl há 4 anos atrás
pai
commit
fe2a7e2c00
2 ficheiros alterados com 22 adições e 2 exclusões
  1. 20 2
      source/forms/CustomScpExplorer.cpp
  2. 2 0
      source/forms/CustomScpExplorer.h

+ 20 - 2
source/forms/CustomScpExplorer.cpp

@@ -215,6 +215,8 @@ __fastcall TCustomScpExplorerForm::TCustomScpExplorerForm(TComponent* Owner):
   FIncrementalSearching = 0;
   FIncrementalSearchHaveNext = false;
   FQueueFileList.reset(new TQueueFileList());
+  FDownloadingFromClipboard = false;
+  FClipboardFakeMonitorsPendingReset = false;
 
   FEditorManager = new TEditorManager();
   FEditorManager->OnFileChange = ExecutedFileChanged;
@@ -4680,6 +4682,12 @@ void __fastcall TCustomScpExplorerForm::Idle()
     UpdateStatusBar();
   }
 
+  if (FClipboardFakeMonitorsPendingReset && !FDownloadingFromClipboard)
+  {
+    FClipboardFakeMonitorsPendingReset = false;
+    FClipboardFakeMonitors.reset(NULL);
+  }
+
   FIgnoreNextDialogChar = 0;
 
 }
@@ -10620,8 +10628,15 @@ void __fastcall TCustomScpExplorerForm::ClipboardStop()
   RemoveDir(ApiPath(FClipboardFakeDirectory));
   FClipboardFakeDirectory = UnicodeString();
   FClipboardTerminal = NULL;
-  // Also called in Idle()
-  FClipboardFakeMonitors.reset(NULL);
+  if (FDownloadingFromClipboard)
+  {
+    // We are called by the monitor, so attempt to release it would deadlonk
+    FClipboardFakeMonitorsPendingReset = true;
+  }
+  else
+  {
+    FClipboardFakeMonitors.reset(NULL);
+  }
 }
 //---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::ClipboardDataObjectRelease(TObject * /*Sender*/)
@@ -10657,7 +10672,10 @@ void __fastcall TCustomScpExplorerForm::ClipboardFakeCreated(TObject * /*Sender*
     {
       if (!NonVisualDataModule->Busy)
       {
+        DebugAssert(!FClipboardFakeMonitorsPendingReset);
+        FClipboardFakeMonitorsPendingReset = false;
         bool NoConfirmation = (WinConfiguration->DDTransferConfirmation == asOff);
+        TAutoFlag Flag(FDownloadingFromClipboard);
         ClipboardDownload(ExtractFilePath(FileName), NoConfirmation, true);
       }
     }

+ 2 - 0
source/forms/CustomScpExplorer.h

@@ -236,6 +236,8 @@ private:
   TObjectList * FDragFakeMonitors;
   UnicodeString FClipboardFakeDirectory;
   std::unique_ptr<TObjectList> FClipboardFakeMonitors;
+  bool FDownloadingFromClipboard;
+  bool FClipboardFakeMonitorsPendingReset;
   std::unique_ptr<TDragDropFilesEx> FClipboardDragDropFilesEx;
   TManagedTerminal * FClipboardTerminal;
   std::unique_ptr<TStrings> FClipboardFileList;