1
0
Martin Prikryl 10 жил өмнө
parent
commit
e52a7fcb90

+ 2 - 0
deployment/winscpsetup.iss

@@ -1324,3 +1324,5 @@ begin
     CreateMutex('WinSCPSilentUninstall');
   Result := True;
 end;
+
+#expr SaveToFile(AddBackslash(SourcePath) + "Preprocessed.iss")

+ 6 - 3
dotnet/Session.cs

@@ -445,11 +445,14 @@ namespace WinSCP
                         }
                         else if (groupReader.IsNonEmptyElement(RemovalEventArgs.Tag))
                         {
-                            if (args == null)
+                            // When "downloading and deleting" a folder,
+                            // we get "rm" tag without preceeding "download" tag.
+                            // So we use only the first "rm" tag after preceeding "download" tag,
+                            // silently ignoring the others
+                            if ((args != null) && (args.Removal == null))
                             {
-                                throw new InvalidOperationException("Tag removal before tag download");
+                                args.Removal = RemovalEventArgs.Read(groupReader);
                             }
-                            args.Removal = RemovalEventArgs.Read(groupReader);
                         }
                     }
 

+ 27 - 5
dotnet/internal/ExeSessionProcess.cs

@@ -7,6 +7,7 @@ using System.Threading;
 using Microsoft.Win32;
 using Microsoft.Win32.SafeHandles;
 using System.Runtime.InteropServices;
+using System.Reflection;
 
 namespace WinSCP
 {
@@ -479,15 +480,36 @@ namespace WinSCP
             }
         }
 
+        private void AddInput(string str)
+        {
+            Type structType = typeof(ConsoleInputEventStruct);
+            FieldInfo strField = structType.GetField("Str");
+            object[] attributes = strField.GetCustomAttributes(typeof(MarshalAsAttribute), false);
+            if (attributes.Length != 1)
+            {
+                throw new InvalidOperationException("MarshalAs attribute not found for ConsoleInputEventStruct.Str");
+            }
+            MarshalAsAttribute marshalAsAttribute = (MarshalAsAttribute)attributes[0];
+
+            if (marshalAsAttribute.SizeConst <= str.Length)
+            {
+                throw new SessionLocalException(
+                    _session,
+                    string.Format(CultureInfo.CurrentCulture, "Input [{0}] is too long ({1} limit)", str, marshalAsAttribute.SizeConst));
+            }
+
+            lock (_input)
+            {
+                _input.Add(str);
+                _inputEvent.Set();
+            }
+        }
+
         public void ExecuteCommand(string command)
         {
             using (_logger.CreateCallstack())
             {
-                lock (_input)
-                {
-                    _input.Add(command);
-                    _inputEvent.Set();
-                }
+                AddInput(command);
             }
         }
 

+ 3 - 3
dotnet/properties/AssemblyInfo.cs

@@ -19,9 +19,9 @@ using System.Runtime.InteropServices;
 // The following GUID is for the ID of the typelib if this project is exposed to COM
 [assembly: Guid("a0b93468-d98a-4845-a234-8076229ad93f")]
 
-[assembly: AssemblyVersion("1.2.7.0")]
-[assembly: AssemblyFileVersion("1.2.7.0")]
-[assembly: AssemblyInformationalVersionAttribute("5.7.1.0")]
+[assembly: AssemblyVersion("1.2.8.0")]
+[assembly: AssemblyFileVersion("1.2.8.0")]
+[assembly: AssemblyInformationalVersionAttribute("5.7.2.0")]
 
 [assembly: CLSCompliant(true)]
 

+ 1 - 1
source/Console.cbproj

@@ -65,7 +65,7 @@
 			<ProjectType>CppConsoleApplication</ProjectType>
 			<SanitizedProjectName>Console</SanitizedProjectName>
 			<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
-			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=Console interface for WinSCP;FileVersion=4.1.0.0;InternalName=console;LegalCopyright=(c) 2000-2015 Martin Prikryl;LegalTrademarks=;OriginalFilename=winscp.com;ProductName=WinSCP;ProductVersion=5.7.1.0;ReleaseType=stable;WWW=http://winscp.net/</VerInfo_Keys>
+			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=Console interface for WinSCP;FileVersion=4.1.0.0;InternalName=console;LegalCopyright=(c) 2000-2015 Martin Prikryl;LegalTrademarks=;OriginalFilename=winscp.com;ProductName=WinSCP;ProductVersion=5.7.2.0;ReleaseType=stable;WWW=http://winscp.net/</VerInfo_Keys>
 			<VerInfo_Locale>1033</VerInfo_Locale>
 			<VerInfo_MajorVer>4</VerInfo_MajorVer>
 			<VerInfo_MinorVer>1</VerInfo_MinorVer>

+ 1 - 1
source/DragExt.cbproj

@@ -66,7 +66,7 @@
 			<SanitizedProjectName>DragExt</SanitizedProjectName>
 			<VerInfo_DLL>true</VerInfo_DLL>
 			<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
-			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=Drag&amp;Drop shell extension for WinSCP (32-bit);FileVersion=1.2.1.0;InternalName=dragext32;LegalCopyright=(c) 2000-2015 Martin Prikryl;LegalTrademarks=;OriginalFilename=dragext.dll;ProductName=WinSCP;ProductVersion=5.7.1.0;ReleaseType=stable;WWW=http://winscp.net/</VerInfo_Keys>
+			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=Drag&amp;Drop shell extension for WinSCP (32-bit);FileVersion=1.2.1.0;InternalName=dragext32;LegalCopyright=(c) 2000-2015 Martin Prikryl;LegalTrademarks=;OriginalFilename=dragext.dll;ProductName=WinSCP;ProductVersion=5.7.2.0;ReleaseType=stable;WWW=http://winscp.net/</VerInfo_Keys>
 			<VerInfo_Locale>1033</VerInfo_Locale>
 			<VerInfo_MinorVer>2</VerInfo_MinorVer>
 			<VerInfo_Release>1</VerInfo_Release>

+ 2 - 2
source/DragExt64.rc

@@ -1,6 +1,6 @@
 1 VERSIONINFO
 FILEVERSION 1,2,1,0
-PRODUCTVERSION 5,7,1,0
+PRODUCTVERSION 5,7,2,0
 FILEOS 0x4
 FILETYPE 0x2
 {
@@ -16,7 +16,7 @@ FILETYPE 0x2
             VALUE "LegalTrademarks", "\0"
             VALUE "OriginalFilename", "dragext64.dll\0"
             VALUE "ProductName", "WinSCP\0"
-            VALUE "ProductVersion", "5.7.1.0\0"
+            VALUE "ProductVersion", "5.7.2.0\0"
             VALUE "ReleaseType", "stable\0"
             VALUE "WWW", "http://winscp.net/\0"
         }

+ 2 - 2
source/WinSCP.cbproj

@@ -83,11 +83,11 @@
 			<SanitizedProjectName>WinSCP</SanitizedProjectName>
 			<UsingDelphiRTL>true</UsingDelphiRTL>
 			<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
-			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=WinSCP: SFTP, FTP and SCP client;FileVersion=5.7.1.0;InternalName=winscp;LegalCopyright=(c) 2000-2015 Martin Prikryl;LegalTrademarks=;OriginalFilename=winscp.exe;ProductName=WinSCP;ProductVersion=5.7.1.0;ReleaseType=stable;WWW=http://winscp.net/</VerInfo_Keys>
+			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=WinSCP: SFTP, FTP and SCP client;FileVersion=5.7.2.0;InternalName=winscp;LegalCopyright=(c) 2000-2015 Martin Prikryl;LegalTrademarks=;OriginalFilename=winscp.exe;ProductName=WinSCP;ProductVersion=5.7.2.0;ReleaseType=stable;WWW=http://winscp.net/</VerInfo_Keys>
 			<VerInfo_Locale>1033</VerInfo_Locale>
 			<VerInfo_MajorVer>5</VerInfo_MajorVer>
 			<VerInfo_MinorVer>7</VerInfo_MinorVer>
-			<VerInfo_Release>1</VerInfo_Release>
+			<VerInfo_Release>2</VerInfo_Release>
 		</PropertyGroup>
 	<PropertyGroup Condition="'$(Base_Win32)'!=''">
 			<Defines>IDE;STRICT;$(Defines)</Defines>

+ 13 - 2
source/components/LogMemo.cpp

@@ -130,6 +130,7 @@ void __fastcall TLogMemo::UpdateFromLog()
   {
     assert(FIndexes->Count == Lines->Count);
     FUpdating = true;
+    bool Updated = false;
     SessionLog->Lock();
     try
     {
@@ -143,7 +144,11 @@ void __fastcall TLogMemo::UpdateFromLog()
           while (Lines->Count && (Indexes[0] < SessionLog->TopIndex))
           {
             FIndexes->Delete(0);
-            if (Parent) Lines->Delete(0);
+            if (Parent)
+            {
+              Lines->Delete(0);
+              Updated = true;
+            }
           }
         }
         __finally
@@ -186,6 +191,7 @@ void __fastcall TLogMemo::UpdateFromLog()
                 {
                   Lines->Add(SessionLog->Line[LastIndex]);
                 }
+                Updated = true;
               }
             }
             catch(...)
@@ -222,6 +228,11 @@ void __fastcall TLogMemo::UpdateFromLog()
       SessionLog->Unlock();
       FUpdating = false;
     }
+
+    if (Updated)
+    {
+      Change();
+    }
   }
 #endif
 }
@@ -396,7 +407,7 @@ void __fastcall TLogMemo::SetParent(TWinControl * AParent)
 //---------------------------------------------------------------------------
 void __fastcall TLogMemo::Change()
 {
-  if (Parent && Visible && !Application->Terminated)
+  if (Parent && Visible && !Application->Terminated && !FUpdating)
   {
     TCustomRichEdit::Change();
   }

+ 6 - 0
source/core/Configuration.cpp

@@ -280,6 +280,12 @@ void __fastcall TConfiguration::DoSave(bool All, bool Explicit)
 //---------------------------------------------------------------------------
 void __fastcall TConfiguration::Export(const UnicodeString & FileName)
 {
+  // not to "append" the export to an existing file
+  if (FileExists(FileName))
+  {
+    DeleteFileChecked(FileName);
+  }
+
   THierarchicalStorage * Storage = NULL;
   THierarchicalStorage * ExportStorage = NULL;
   try

+ 4 - 0
source/core/SecureShell.cpp

@@ -2339,6 +2339,10 @@ void __fastcall TSecureShell::CollectUsage()
   {
     Configuration->Usage->Inc(L"OpenedSessionsSSHApache");
   }
+  else if (ContainsText(FSessionInfo.SshImplementation, L"OpenVMS"))
+  {
+    Configuration->Usage->Inc(L"OpenedSessionsSSHOpenVMS");
+  }
   else
   {
     Configuration->Usage->Inc(L"OpenedSessionsSSHOther");

+ 17 - 2
source/core/SftpFileSystem.cpp

@@ -127,6 +127,10 @@
 
 #define SSH_FILEXFER_ATTR_FLAGS_HIDDEN           0x00000004
 
+#define SSH_FXP_REALPATH_NO_CHECK    0x00000001
+#define SSH_FXP_REALPATH_STAT_IF     0x00000002
+#define SSH_FXP_REALPATH_STAT_ALWAYS 0x00000003
+
 #define SFTP_MAX_PACKET_LEN   1024000
 //---------------------------------------------------------------------------
 #define SFTP_EXT_OWNER_GROUP "owner-group-query@generic-extensions"
@@ -2669,7 +2673,7 @@ UnicodeString __fastcall TSFTPFileSystem::RealPath(const UnicodeString Path)
     // Earlier versions had no recommendation, though canonical SFTP-3 implementation
     // in OpenSSH fails.
 
-    // While we really do not care much, we anyway set the flag to 0 to make the request fail.
+    // While we really do not care much, we anyway set the flag to ~ & 0x01 to make the request fail.
     // First for consistency.
     // Second to workaround a bug in ProFTPD/mod_sftp version 1.3.5rc1 through 1.3.5-stable
     // that sends a completelly malformed response for non-existing paths,
@@ -2681,7 +2685,18 @@ UnicodeString __fastcall TSFTPFileSystem::RealPath(const UnicodeString Path)
     // if may cause trouble.
     if (FVersion >= 6)
     {
-      Packet.AddByte(0);
+      if (FSecureShell->SshImplementation != sshiProFTPD)
+      {
+        Packet.AddByte(SSH_FXP_REALPATH_STAT_ALWAYS);
+      }
+      else
+      {
+        // Cannot use SSH_FXP_REALPATH_STAT_ALWAYS as ProFTPD does wrong bitwise test
+        // so it incorrectly evaluates SSH_FXP_REALPATH_STAT_ALWAYS (0x03) as
+        // SSH_FXP_REALPATH_NO_CHECK (0x01). The only value conforming to the
+        // specification, yet working with ProFTPD is SSH_FXP_REALPATH_STAT_IF (0x02).
+        Packet.AddByte(SSH_FXP_REALPATH_STAT_IF);
+      }
     }
     SendPacketAndReceiveResponse(&Packet, &Packet, SSH_FXP_NAME);
     if (Packet.GetCardinal() != 1)

+ 9 - 6
source/core/Terminal.cpp

@@ -629,7 +629,7 @@ __fastcall TTerminal::TTerminal(TSessionData * SessionData,
   FTunnelUI = NULL;
   FTunnelOpening = false;
   FCallbackGuard = NULL;
-  FIdle = 0;
+  FNesting = 0;
 }
 //---------------------------------------------------------------------------
 __fastcall TTerminal::~TTerminal()
@@ -666,11 +666,13 @@ __fastcall TTerminal::~TTerminal()
 //---------------------------------------------------------------------------
 void __fastcall TTerminal::Idle()
 {
-  // once we disconnect, do nothing, until reconnect handler
-  // "receives the information"
-  if (Active)
+  // Once we disconnect, do nothing, until reconnect handler
+  // "receives the information".
+  // Never go idle when called from within ::ProcessGUI() call
+  // as we may recurse for good, timeouting eventually.
+  if (Active && (FNesting == 0))
   {
-    TAutoNestingCounter IdleCounter(FIdle);
+    TAutoNestingCounter NestingCounter(FNesting);
 
     if (Configuration->ActualLogProtocol >= 1)
     {
@@ -1084,8 +1086,9 @@ void __fastcall TTerminal::ProcessGUI()
   // Do not process GUI here, as we are called directly from a GUI loop and may
   // recurse for good.
   // Alternatively we may check for (FOperationProgress == NULL)
-  if (FIdle == 0)
+  if (FNesting == 0)
   {
+    TAutoNestingCounter NestingCounter(FNesting);
     ::ProcessGUI();
   }
 }

+ 1 - 1
source/core/Terminal.h

@@ -203,7 +203,7 @@ private:
   bool FCollectFileSystemUsage;
   bool FRememberedPasswordTried;
   bool FRememberedTunnelPasswordTried;
-  int FIdle;
+  int FNesting;
 
   void __fastcall CommandError(Exception * E, const UnicodeString Msg);
   unsigned int __fastcall CommandError(Exception * E, const UnicodeString Msg,

+ 4 - 2
source/core/WebDAVFileSystem.cpp

@@ -173,7 +173,8 @@ static UTF8String PathUnescape(const char * Path)
 #define StrToNeon(S) UTF8String(S).c_str()
 #define StrFromNeon(S) UnicodeString(UTF8String(S))
 #define AbsolutePathToNeon(P) PathEscape(StrToNeon(P)).c_str()
-#define PathToNeon(P) AbsolutePathToNeon(AbsolutePath(P, false))
+#define PathToNeonStatic(THIS, P) AbsolutePathToNeon((THIS)->AbsolutePath(P, false))
+#define PathToNeon(P) PathToNeonStatic(this, P)
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
 void __fastcall NeonInitialize()
@@ -875,7 +876,8 @@ void TWebDAVFileSystem::NeonPropsResult(
   TReadFileData & Data = *static_cast<TReadFileData *>(UserData);
   if (Data.FileList != NULL)
   {
-    if (UnixSamePath(Path, Data.FileList->Directory))
+    UnicodeString FileListPath = PathToNeonStatic(Data.FileSystem, Data.FileList->Directory);
+    if (UnixSamePath(Path, FileListPath))
     {
       Path = UnixIncludeTrailingBackslash(Path) + L"..";
     }

+ 1 - 1
source/forms/Log.cpp

@@ -143,7 +143,7 @@ void __fastcall TLogForm::FormClose(TObject * /*Sender*/, TCloseAction & Action)
   else
   {
     WinConfiguration->LogView = lvNone;
-    Action = caFree;
+    Action = caNone;
   }
   WinConfiguration->LogWindowParams = StoreForm(this);
 }

+ 10 - 2
source/forms/Progress.cpp

@@ -552,7 +552,15 @@ void __fastcall TProgressForm::ApplyCPSLimit()
   SpeedCombo->Text = SetSpeedLimit(FCPSLimit);
   // visualize application
   SpeedCombo->SelectAll();
-  CancelButton->SetFocus();
+  ResetFocus();
+}
+//---------------------------------------------------------------------------
+void __fastcall TProgressForm::ResetFocus()
+{
+  if (CancelButton->Enabled)
+  {
+    CancelButton->SetFocus();
+  }
 }
 //---------------------------------------------------------------------------
 void __fastcall TProgressForm::SpeedComboExit(TObject * /*Sender*/)
@@ -610,7 +618,7 @@ void __fastcall TProgressForm::OnceDoneOperationCombo2Select(TObject * /*Sender*
 //---------------------------------------------------------------------------
 void __fastcall TProgressForm::OnceDoneOperationCombo2CloseUp(TObject * /*Sender*/)
 {
-  CancelButton->SetFocus();
+  ResetFocus();
 }
 //---------------------------------------------------------------------------
 void __fastcall TProgressForm::Dispatch(void * AMessage)

+ 1 - 0
source/forms/Progress.h

@@ -91,6 +91,7 @@ private:
   void __fastcall SetReadOnly(bool value);
   void __fastcall GlobalMinimize(TObject * Sender);
   void __fastcall ApplicationModalBegin(TObject * Sender);
+  void __fastcall ResetFocus();
 
 protected:
   void __fastcall CancelOperation();

+ 2 - 0
source/packages/jcl/JclDebug.pas

@@ -4363,6 +4363,8 @@ begin
       begin
         ModuleName := ExtractFileName(GetModulePath(Module));
         ModulePosition := 12 {$IFDEF CPU64}+8{$ENDIF};
+        if IncludeVAddress then
+          ModulePosition := 2 * (ModulePosition - 1) + 1;
         if ModulePosition < Length(Result) then
           ModuleName := ModuleName + '.';
         Insert(ModuleName, Result, ModulePosition);

+ 1 - 1
source/windows/VCLCommon.cpp

@@ -363,7 +363,7 @@ inline void __fastcall DoFormWindowProc(TCustomForm * Form, TWndMethod WndProc,
   if ((Message.Msg == WM_SYSCOMMAND) &&
       (Message.WParam == SC_CONTEXTHELP))
   {
-    InvokeHelp(Form->ActiveControl);
+    FormHelp(Form);
     Message.Result = 1;
   }
   else if (Message.Msg == CM_SHOWINGCHANGED)

+ 20 - 4
source/windows/WinInterface.cpp

@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------
 TNotifyEvent GlobalOnMinimize = NULL;
 //---------------------------------------------------------------------
-void __fastcall FormHelp(TForm * Form)
+void __fastcall FormHelp(TCustomForm * Form)
 {
   InvokeHelp(Form->ActiveControl != NULL ? Form->ActiveControl : Form);
 }
@@ -522,9 +522,25 @@ static TStrings * __fastcall StackInfoListToStrings(
   TJclStackInfoList * StackInfoList)
 {
   std::unique_ptr<TStrings> StackTrace(new TStringList());
-  StackInfoList->AddToStrings(StackTrace.get(), true, false, true, false);
-  // get rid of __fastcall declarations that are included in .map
-  StackTrace->Text = ReplaceStr(StackTrace->Text, L"__fastcall ", L"");
+  StackInfoList->AddToStrings(StackTrace.get(), true, false, true, true);
+  for (int Index = 0; Index < StackTrace->Count; Index++)
+  {
+    UnicodeString Frame = StackTrace->Strings[Index];
+    // get rid of declarations "flags" that are included in .map
+    Frame = ReplaceStr(Frame, L"__fastcall ", L"");
+    Frame = ReplaceStr(Frame, L"__linkproc__ ", L"");
+    if (ALWAYS_TRUE(!Frame.IsEmpty() && (Frame[1] == L'(')))
+    {
+      int Start = Frame.Pos(L"[");
+      int End = Frame.Pos(L"]");
+      if (ALWAYS_TRUE((Start > 1) && (End > Start) && (Frame[Start - 1] == L' ')))
+      {
+        // remove absolute address
+        Frame.Delete(Start - 1, End - Start + 2);
+      }
+    }
+    StackTrace->Strings[Index] = Frame;
+  }
   return StackTrace.release();
 }
 //---------------------------------------------------------------------------

+ 1 - 1
source/windows/WinInterface.h

@@ -70,7 +70,7 @@ void __fastcall SetOnForeground(bool OnForeground);
 void __fastcall FlashOnBackground();
 
 void __fastcall ShowExtendedExceptionEx(TTerminal * Terminal, Exception * E);
-void __fastcall FormHelp(TForm * Form);
+void __fastcall FormHelp(TCustomForm * Form);
 void __fastcall SearchHelp(const UnicodeString & Message);
 void __fastcall MessageWithNoHelp(const UnicodeString & Message);