1
0
mirror of https://github.com/winscp/winscp.git synced 2026-10-24 02:28:55 +03:00

4869 Commits

Author SHA1 Message Date
Martin Prikryl
f998f3e79f Issue 2477 – Recursive SCP directory download allows local path traversal when replacing of invalid characters in filenames is disabled
https://winscp.net/tracker/2477

Source commit: ce8dfc6e513236dd3b3d1f776e875f46761817fc
2026-10-24 00:40:07 +02:00
Martin Prikryl
bd10c64863 Due to wrong compiler directive, old-style casts were omitted in e5efed89
Source commit: 9864e1dc6f39b5b029461f8850c068c6d3b1a487
2026-10-24 00:39:18 +02:00
Martin Prikryl
2f87f77952 Fixing operator
Source commit: fb6d4d145949a9e13ec7d620435565f090b16d85
2026-10-24 00:37:42 +02:00
Martin Prikryl
6f39a04987 Issue 2475 – Support client certificates with intermediate certificate
https://winscp.net/tracker/2475

Source commit: 7075ae74fd7e6cd92ed8d8e7422528dc56743158
2026-10-22 00:36:04 +02:00
Martin Prikryl
6542254ab9 Fix compile error by a8fc40bd
NULL cannot be used with closure in ternary operator

Source commit: f8e68bf54e4d8ce76e5f0cd7ee4bc27cd2528daf
2026-10-21 07:43:16 +02:00
Martin Prikryl
094515154c Issue 1950 – Parsing of multiline VMS FTP listing entries is broken
The previous fix from e757f7b7 only fixed a small part of the problem (before the parsing result was corrupted, while after the fix file details were not parsed).

https://winscp.net/tracker/1950

Source commit: 2853e4d6abe65217f72ab4f8f840b1a15b1184d6
2026-10-21 00:35:21 +02:00
Martin Prikryl
3a3c431786 Issue 2474 – Failure when SSH authentication banner is displayed while reconnecting a session
https://winscp.net/tracker/2474

Source commit: 15d2da2605dc40a7fd6601d32b1f6d6625c591b3
2026-10-20 16:14:05 +02:00
Eduardo C.
a8fc40bd0e Portability: let core build with clang on Linux and Windows (#79)
* Cast between closure types with a functional cast, not reinterpret_cast

A Borland __closure is a built-in (code, data) pair, so reinterpret_cast
between two closure types is allowed. Under standard C++ a closure is a
class, and reinterpret_cast cannot convert one class object into another.
The functional cast is the old C-style cast this line had before
"Refactoring old-style casts" (e5efed895), so C++Builder compiles it as it
did then, and a compiler implementing closures as classes can give it the
same meaning.

* Read the knocked FTP port's IPv4 address as 32 bits

The address is read through an unsigned long pointer. That is 32 bits on
Windows (LLP64), so it reads exactly the four address bytes there; on LP64
targets unsigned long is 64 bits, and the read runs four bytes past the
address into whatever follows it in gethostbyname's buffer. The assignment
to the 32-bit s_addr then keeps the right bytes on little-endian machines,
which is why it goes unnoticed, but the over-read is undefined. ULONG is 32
bits on every Windows compiler, as Windows API layers for POSIX define it
too.

* Compile the synchronize checklist's Explorer file operation on Windows only

TSynchronizeChecklistFileOperation carries out a synchronization checklist
through Explorer's IFileOperation (a Shell COM object), so that local
deletions go to the recycle bin with Explorer's progress and undo. Only
WinSCP's Windows GUI uses it (CustomScpExplorer.cpp). Elsewhere neither the
object nor the interfaces exist, and declaring them only to compile would
pretend to a facility that is not there; a frontend on another platform
implements the operation its own way. The class and its implementation are
guarded with _WIN32, which C++Builder defines, so the Windows build is
unchanged.

* Declare the SIOCATMARK result as ULONG, the type p_ioctlsocket takes

network.c declares ioctlsocket as taking ULONG * (its DECL_WINDOWS_FUNCTION)
but passes a u_long. Both are 32 bits on Windows, so the two agree there. On
an LP64 platform u_long is 64 bits and ULONG 32, so the pointer types differ
and the callee would write half the variable. ULONG is what the declaration
says, and is the same type on Windows.

* Pick aes-ni.c's _mm_setr_epi8 for any GCC-compatible compiler

MM_SETR_EPI8 uses _mm_setr_epi8 only under _WIN64, falling back to a brace
initialiser that is correct for MSVC's __m128i (a byte union) but fills
clang's and GCC's (a two-lane vector) wrongly; the _WIN64 condition fixed
that for Win64 builds only. Any compiler defining __GNUC__ (clang does) now
takes the intrinsic.

* Compile WinSCP's Windows-only additions to neon on Windows only

WinSCP builds neon for Win32 alone, and three of its additions assume it:
ne_openssl.c includes <windows.h> (it uses nothing from it), timed_connect
switches the socket to non-blocking mode with Winsock's ioctlsocket instead
of upstream's fcntl, and ne_sock_sspi_init calls into SSPI unconditionally.
On POSIX neon uses BSD sockets directly, so the include is guarded with
_WIN32, the two ioctlsocket branches are taken only on _WIN32 (upstream's
fcntl code beside them is used otherwise), and ne_sock_sspi_init calls SSPI
under HAVE_SSPI, as ne_sock_init's own call does, reporting failure (-1)
without it -- which WebDAVFileSystem.cpp already handles as SSPI being
unavailable. C++Builder defines _WIN32 and neon's Win32 config.h defines
HAVE_SSPI, so the Windows build is unchanged.

* Use in_addr's s_addr in FileZilla's proxy layer

AsyncProxySocketLayer.cpp reaches the IPv4 address through Winsock's union,
sin_addr.S_un.S_addr. Winsock also defines s_addr as exactly that member
(#define s_addr S_un.S_addr), and s_addr is the name BSD sockets and POSIX
give the field; a POSIX in_addr has no S_un. Same field, so the Windows
build is unchanged.

* Pass FileZilla's two tool strings as UnicodeString, not std::wstring

CFileZillaTools::GetClientString and CustomReason return std::wstring; the
rest of the interface between core and FileZilla, and both sides' own code,
use UnicodeString or wchar_t pointers. Built with a 2-byte wchar_t on a
platform whose C++ library assumes 4 (clang's -fshort-wchar on Linux),
std::wstring is unusable: libstdc++ provides basic_string<wchar_t> as a
precompiled extern template for its own wchar_t, and char_traits<wchar_t>
calls the C library's 4-byte wcslen and wmemcpy: a Linux build of
FtpFileSystem.cpp imported wcslen through it. The values are only built from
UnicodeString, compared with empty() and read with c_str(), so UnicodeString
is a direct replacement (IsEmpty for empty). On Windows, where wchar_t is 2
bytes throughout, behaviour is unchanged.

* Build storage key paths with backslashes on every platform

THierarchicalStorage joins registry and INI key paths (Sessions\My site)
through its IncludeTrailingBackslash and ExcludeTrailingBackslash members,
which defer to the RTL functions of those names. The RTL's add and strip the
platform's path delimiter: a backslash on Windows, a slash on POSIX, where
these functions also build local file paths. Keys are not file paths: their
separator is a backslash everywhere, and the INI file's sections say so. The
members now add and strip a backslash themselves; on Windows that is what
the RTL did, so the behaviour there is unchanged. Without this, on POSIX the
current key became "Sessions/", matched no section, and no stored site
loaded.

* Hand neon a copy of the TLS-init closure, not its two pointers

SetNeonTlsInit stores the closure in the neon session by reinterpreting it
as a TMethod and saving its code and data pointers, and ne_init_ssl_session
rebuilds it with MakeMethod. That relies on a closure being exactly those
two pointers, which only Borland's __closure is; with any other closure type
the saved words are its internals, read from a by-value parameter that is
gone by the time neon calls back, and the rebuilt closure is garbage (a
clang build's first WebDAV-over-TLS connection crashed there). The session
now holds a heap copy of the closure, freed by neon's destroy-session hook
-- which also covers the sessions libs3 creates and destroys itself -- and
ne_init_ssl_session calls that copy. On C++Builder the behaviour is the
same, at the cost of one small allocation per session.

* Take CString's search results as const wchar_t *

CString::Find, ReverseFind and FindOneOf search the const string c_str()
returns and keep the result in a wchar_t *. ISO C++ declares wcschr,
wcsrchr, wcsstr and wcspbrk on a const string as returning const wchar_t *,
as MSVC's and newer mingw-w64 headers (llvm-mingw's) do, so the
initialisation does not compile there. The pointers are only compared and
subtracted: const is all they need.

* Index the string a string-list property returns, not the property

GetLocales takes a character of Exts->Strings[Index]. Under clang the
__declspec(property) standing for TStrings::Strings' __property reads a
second subscript as the property's own second index, so the expression is a
two-argument call to the getter and does not compile (parentheses do not
change that). Read into a UnicodeString first, the second subscript indexes
the string the property returns, as under C++Builder.

---------

Co-authored-by: Eduardo Correia <ecorreia@apliant.com.br>
2026-10-20 16:01:54 +02:00
Eduardo C.
a2fb90bebb Keep an OpenSSH config's paths POSIX ones on POSIX (#83)
ConvertPathFromOpenssh turns the forward slashes of an OpenSSH config's
paths into backslashes (GetNormalizedPath), as Windows' dialogs want them.
On POSIX that breaks the path: an imported site's IdentityFile
~/.ssh/id_ed25519 became \home\user\.ssh\id_ed25519, a file that does not
exist. 

---------

Co-authored-by: Eduardo Correia <ecorreia@apliant.com.br>
2026-10-19 15:43:41 +02:00
Eduardo C.
be3b6cd15d Make the local end of line the platform's (#82)
TConfiguration::GetLocalEOLType always says CRLF: core has only run on
Windows, where local text files end their lines so. Text-mode transfers
convert to and from it (SFTP, SCP), so on POSIX a text-mode download gave
local files CRLF line endings, which POSIX programs do not expect, and the
internal editor would have written them back so. 

---------

Co-authored-by: Eduardo Correia <ecorreia@apliant.com.br>
2026-10-19 15:11:57 +02:00
Eduardo Correia
fa44986109 Load S3 tags for files only, as the Properties dialog shows them
LoadFilesProperties asks DoLoadFileProperties for tags whenever a single
entry is selected, a folder too, although the Properties dialog shows tags
for files only. A folder that is only a prefix of its objects' keys -- as
folders made by other tools often are -- has no object of its own to read
tags from: GetObjectTagging answers NoSuchKey, and the folder's Properties
fail. Tags are now loaded for files only.
2026-10-19 15:00:08 +02:00
Eduardo Correia
9d221f6ac0 Load an S3 object's properties from servers that keep no object ACLs
DoLoadFileProperties reads the object's ACL before its tags and fails on any
error, so on a server that implements no object ACLs -- versitygw answers
GetObjectAcl with 501 NotImplemented, as do other S3-compatible servers --
the Properties dialog does not open at all, the tags included. A
NotImplemented answer now reads as an ACL with no grants; any other error
still fails as before.
2026-10-19 14:50:20 +02:00
Martin Prikryl
1ffd65ce61 Avoid compiler warning
Source commit: dc224a69378f5503c29b494282f4e222fab0f446
2026-10-17 00:34:31 +02:00
Eduardo Correia
1189d26eb8 Build the default log file names with the platform's path delimiter
The session log's and the XML log's defaults are written as literals,
%TEMP%\!S.log and %TEMP%\!S.xml. On POSIX the backslash is not a path
delimiter, so the log was created beside the temporary directory, named
"tmp\!S.log", instead of in it. Built with IncludeTrailingBackslash, as the
random seed file's default already is, the delimiter is the platform's: on
Windows the same backslash as before, so the behaviour there is unchanged.
2026-10-16 14:15:17 +02:00
Eduardo Correia
63a6579fac Define TTerminal::LogEvent out of line, as the files calling it need
TTerminal::LogEvent is defined `inline` in Terminal.cpp, but the file
systems (FtpFileSystem.cpp and others) call it too. An inline function must
be defined in every translation unit that uses it; when it is not, the
program is ill-formed, and whether it links depends on the compiler keeping
an out-of-line copy. An optimizing clang build (-O2, -O3) inlines every call
within Terminal.cpp and emits none, so the other files' calls are undefined
at link time. Without `inline` the definition is the one every caller links
to; the calls within Terminal.cpp may still be inlined.
2026-10-16 13:45:16 +02:00
Eduardo C.
101189ca27 Translate old-format RSA host keys in retrieve_host_key (#75)
* Translate old-format RSA host keys in retrieve_host_key

retrieve_host_key comes from PuTTY's check_stored_host_key, where key is the
server's key and an old-format registry entry is translated and kept only if
it matches. In retrieve_host_key key is the output buffer, so the
translation is compared with whatever the caller's buffer holds (TSecureShell
passes an uninitialised one) and in practice never matches: an old-format
host key is reported as not cached.

The translation is now returned as the stored key, for the caller to compare
with the server's key, as it compares every other stored key. It is not
written back in the new format, as nothing here has verified it.

* Keep the original strbuf_to_str in retrieve_host_key's old-format path

Exclude only the comparison, the put_reg_sz and the else (#ifndef WINSCP),
so that it is clear the strbuf_to_str is what the original does when the
key matches.

---------

Co-authored-by: Eduardo Correia <ecorreia@apliant.com.br>
2026-10-16 11:47:21 +02:00
Martin Prikryl
9f762aed94 Merge branch 'master' into dev
Source commit: ecc2a617254488c19215c8d63f44d0b497c8e91a
2026-10-16 11:18:40 +02:00
Martin Prikryl
53f8213112 Moving abnormal program termination handling to reduce interface
Source commit: 528cf0238d2af829fcc8481bd2452e1ba2ef7832
2026-10-16 11:08:10 +02:00
Build Server
ec328f18f1 Letter casing in filename
Source commit: bfe6ab0ffce08654cf659554c2924befa72f8383
2026-10-15 16:21:59 +02:00
Martin Prikryl
98c7eeb154 Merge branch 'master' into dev
# Conflicts:
#	source/WinSCP.cbproj

Source commit: aaed26e971961f1564e464528796506f363fb720
2026-10-14 14:12:55 +02:00
Martin Prikryl
e19a9a3ec4 Bumping devel version to stable 6.7.1
Source commit: a33c96ee562c0459267a519b2561f28614432a4d
2026-10-14 14:01:10 +02:00
Martin Prikryl
00f664e86f Bumping devel version to stable 6.7
Source commit: 1cf02d11e9ebfe51b188723429e7a6c7768a2271
2026-10-14 10:27:10 +02:00
Eduardo Correia
8f67d22382 Give script rmdir's directory entries a full path
For rmdir, TScript::CreateFileList (fltDirectories) creates a bare
TRemoteFile with only its name and type: no directory list and no full
file name. TWebDAVFileSystem::DeleteFile takes the path from
File->FullFileName, and TRemoteFile::GetFullFileName then dereferences the
null Directory. With WinSCP 6.5.7 a script doing

  mkdir /work/gone
  rmdir /work/gone

over WebDAV fails with "Invalid access to memory" in
TRemoteFileList::GetFullDirectory (from TWebDAVFileSystem::FilePath,
TTerminal::DoDeleteFile, TScript::RmDirProc).

The entry now carries its absolute path, resolved as TTerminal::DoDeleteFile
resolves the same name. Protocols that use the file name (SFTP, SCP, FTP)
are unaffected; WebDAV now deletes the directory.
2026-10-13 14:08:14 +02:00
Eduardo Correia
d6dd4c7ec8 Free the Ed448 curve in ec_cleanup
ec_cleanup frees every curve ecc-ssh.c sets up except Ed448: ec_ed448 lacks
the WINSCP_CURVE_CLEANUP its siblings have and ec_cleanup does not call it,
so its points and bignums leak at shutdown once an Ed448 key was used.
2026-10-13 11:16:37 +02:00
Eduardo Correia
be053db0a6 Forget the freed system directory in win_misc_cleanup
win_misc_cleanup frees get_system_dir's cached buffer but leaves the pointer
and its size, so a get_system_dir call after the cleanup returns freed
memory instead of fetching the directory again.
2026-10-13 11:13:14 +02:00
Eduardo Correia
d89d03e5df Leave the PuTTY section when random_add_noise returns early
random_add_noise enters putty_section and then returns without leaving it
when the generator is not active. The section is recursive, so the thread
that returned keeps working, but any other thread entering it -- another
session's socket, RNG or bignum code -- then blocks for good.
2026-10-13 11:10:16 +02:00
Eduardo Correia
4e9af64b9c Pop aes-ni.c's clang attribute under the condition it was pushed
aes-ni.c pushes its target attribute under #ifdef __clang__ but pops it
under #ifdef _WIN64. For clang targeting Win64 the two coincide. Otherwise
they do not: clang targeting 32-bit Windows (clang-cl in a WINSCP_VS build)
reports the push as unterminated and fails, and MSVC targeting x64 meets a
pop of a clang pragma it does not know (warning C4068). The pop now has the
push's condition.
2026-10-13 11:03:41 +02:00
Eduardo Correia
1c4e584fe9 Swap GetParentProcessId's memset arguments back
memset takes the fill value before the size, so
memset(&ProcessEntry, sizeof(ProcessEntry), 0) zeroed nothing. It was
harmless, as Process32First fills the entry it reads, but the entry is now
cleared as intended.
2026-10-13 10:57:49 +02:00
Eduardo Correia
8a82e298f8 Close the handle FileGetSymLinkTargetSafe opens
FileGetSymLinkTargetSafe opens the link with CreateFile to read its reparse
point, but never closes the handle, so each call leaks one. DriveView calls
it for every symbolic link and junction it lists.
2026-10-13 10:52:56 +02:00
Martin Prikryl
b5f56bd2d4 Unused code
Inspired by PR #68

Source commit: 9c96e906501d8a22d305aa24ccf3162a287feb40
2026-10-13 10:47:52 +02:00
Martin Prikryl
69edabbe2d Issue 2469 – Failure when using options in button drop down menus on Overwrite confirmation box
https://winscp.net/tracker/2469

Source commit: 51281856e8bae26ce21ae495f726c91a72f5ff03
2026-10-13 00:38:14 +02:00
Martin Prikryl
78ef7c2cb7 Issue 2468 – Failure when keeping remote directory up to date
https://winscp.net/tracker/2468

Source commit: c75cda631f3837d27f311f66f2fb90d225e1bd1a
2026-10-13 00:36:43 +02:00
Martin Prikryl
05616dc742 Fixing stacktrace collection for abnormal program termination for 64-bit build
Source commit: d211d0525413d5b9a06ea25c788fa3d1377c68f3
2026-10-13 00:35:57 +02:00
Martin Prikryl
aaae9dcb51 Allowing to report abnormal program terminations + Handling all types of exceptions
Source commit: 469bb8038a53cf2510d92222e66351ba3c6c4a66
2026-10-10 00:36:12 +02:00
Martin Prikryl
4fc182de35 Forgotten declaration
Should have been removed in a6916d41

Source commit: 56826244476f1b2e80aa109510456f82d5615fc4
2026-10-08 00:35:55 +02:00
Martin Prikryl
ae3a2899c5 Dummy placeholder for changes in 6.8
Source commit: 4f83e9721b8ad970743f97160bce36758fb239d6
2026-10-08 00:35:07 +02:00
Martin Prikryl
009194d9ea Bumping devel version to 6.8
Source commit: ff9506f66874b3bc16a71ee382faac9882ae96f1
2026-10-07 16:40:37 +02:00
Martin Prikryl
c6a4c7a4b2 Merge branch 'master' into dev
Source commit: 0bfc0cc0a7b4bc5476bf59dbd2026754b90db912
2026-10-07 16:38:44 +02:00
Martin Prikryl
c057d1d62c Bumping devel version to 6.6.5
Source commit: 7414ce374e4876772f7e49f55526a0ebe63f2360
2026-10-07 16:37:59 +02:00
Martin Prikryl
ac781f63fe Update to Expat 2.9.0
Source commit: 2d2fc87baa17104082d3ddaab96216a3f342f60a
2026-10-07 11:03:29 +02:00
Martin Prikryl
2724e8a53f Issue 2466 – Temporary directory structure for edited remote file reflected the current remote directory path rather than an actual path of the edited file
https://winscp.net/tracker/2466

Source commit: 639bddac91fecf53e0c3b5fd5835e9dd1c5ab0a5
2026-10-07 11:01:58 +02:00
Martin Prikryl
b6b2b34acf Obsolete comment
Source commit: dcb9f632e911b3f04ee9a42ed0126ce98b0e236a
2026-10-07 00:38:28 +02:00
Martin Prikryl
0b3eca59ad Not scanning local directory symlinks pointing to network drives
Source commit: 19baa413392caabbb7afea6eb2b925cc98ca5076
2026-10-07 00:36:56 +02:00
Martin Prikryl
a9fa4a583a Translating TDriveViewInt's ReadSubDirs, DoScanDir and AddChildNode to C++ before modifying them
Source commit: f8c0cdbb0c4e8665eac9a9b9526d6714ed6457cf
2026-10-07 00:36:09 +02:00
Martin Prikryl
5b449266fb Merge branch 'master' into dev
Source commit: 3f0bb4b04b569e6f775042500ebbf49f62962782
2026-10-04 00:35:06 +02:00
Martin Prikryl
a6916d4101 Unused code obsoleted by 64050d10
Source commit: 92ea806f97f6683c5e5158c7236b49ce04aa620c
2026-10-03 08:42:27 +02:00
Martin Prikryl
86413f4712 Removing some unused Jcl code
Source commit: 72d2f60cf89412442d2f4029cb43ae9d02ed2636
2026-10-03 08:41:44 +02:00
Martin Prikryl
0707234bbe Removing all debug info sources except for .map file
Seems to have no significant impact on release build (have some on debug build).
With 64-bit build, no impact at all. With 32-bit, there are some differences, but all seem to be in misidentified frames anyway (which are volatile, so the impact might not be due to change in sources)

Source commit: b8d538dd403c7f78778247278bed6e685a5589fb
2026-10-01 00:37:56 +02:00
Martin Prikryl
e13157118a Using themed button drop down menu on Overwrite confirmation box
Source commit: ca02aa76c6041990b5341fecf5f5c25f74a9b2a2
2026-09-30 00:37:29 +02:00
Martin Prikryl
55800c95bd Issue 2463 – Show keyboard accelerators on overwrite confirmation box when keyboard modifier is pressed
https://winscp.net/tracker/2463

Source commit: 493db416a23e77c36621f7443eafbcb685a3512a
2026-09-30 00:35:59 +02:00