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

1580 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
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
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
Martin Prikryl
53f8213112 Moving abnormal program termination handling to reduce interface
Source commit: 528cf0238d2af829fcc8481bd2452e1ba2ef7832
2026-10-16 11:08: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
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
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
ac781f63fe Update to Expat 2.9.0
Source commit: 2d2fc87baa17104082d3ddaab96216a3f342f60a
2026-10-07 11:03:29 +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
a6916d4101 Unused code obsoleted by 64050d10
Source commit: 92ea806f97f6683c5e5158c7236b49ce04aa620c
2026-10-03 08:42:27 +02:00
Martin Prikryl
64050d10c7 Removing no longer working OneDrive code
Source commit: 8a28dd98ba1cf2216dbd176900d23c8acf13685c
2026-09-25 00:36:53 +02:00
Martin Prikryl
e9b1860006 Link updates
Source commit: d947e04bdfdcaec955178b255bad454e9e9fa84a
2026-09-03 16:40:56 +02:00
Martin Prikryl
d47792f01c Issue 2455 – Some strings use incorrect translation in 64-bit version
https://winscp.net/tracker/2455

Some related refactoring:
Refactoring php release script includes
Reusing complete_translations in copy_complete_translations.php
Removing obsolete maketran.bat hack

Source commit: 07476ec822e4bd7b8b1c65ceb9783b6d92f20489
2026-09-01 12:53:54 +02:00
Martin Prikryl
11ce2859c0 Links update
Source commit: a99ad766ce70165b2aa13cc27bb88f8bd4a57893
2026-09-01 12:52:09 +02:00
Martin Prikryl
fa93a30522 Typo in logging
Source commit: bf9cbf2d4816647d3efc2890d0c533f17d6a9248
2026-08-25 10:14:29 +02:00
Martin Prikryl
7221bf08e3 Bug fix: 64-bit build did not identify its system to be 64-bit, what among other prevented it from identifying 64-bit COM registrations
Source commit: dd523846faab989b5bc6d69066da6cde6daa5dbb
2026-08-21 16:10:16 +02:00
Martin Prikryl
7458a02b23 Bug fix: Incorrect number validation
For example causes inability to add a location profile with name like "1M"

Source commit: 324abb63b5746414e990dd499fecb174c104545e
2026-08-02 13:17:50 +02:00
Martin Prikryl
a269e58826 Bug fix: x-name URL parameter was incorrectly decoded
Source commit: be5c17cde1f823e24389834032d88299366963e0
2026-06-26 01:02:43 +02:00
Martin Prikryl
39c95dc289 64-bit build is identified in version information
Source commit: a39a12d3ced2aa3d86b4a2c721df4444a0b03d57
2026-06-26 00:55:08 +02:00
Martin Prikryl
b66c08b30a Issue 2450 – Slashes in filenames can cause path traversal when invalid filename characters replacement is disabled
https://winscp.net/tracker/2450

Source commit: dbf555cdba84101ff9a4e2e491544515a5a95b54
2026-06-16 00:50:07 +02:00
Martin Prikryl
927e5f538a Issue 2449 – Heap over-read via crafted encrypted filename
https://winscp.net/tracker/2449

Source commit: b3d37ef6d446a33900eb2ba2e911d1134c1bd312
2026-06-13 01:04:26 +02:00
Martin Prikryl
dc56db76b1 Issue 2447 – Do not allow WebDAV redirects to other hosts by default + Issue 2448 – Do not allow WebDAV redirects to an unencrypted URL by default
https://winscp.net/tracker/2447
https://winscp.net/tracker/2448

Source commit: c777084ca5737c4283f256eb8cdf5c2fec5902af
2026-06-13 01:00:40 +02:00
Martin Prikryl
e500e57baa URI class
Source commit: baa68e01bcc829b3c66842aec637fe1b6febd48a
2026-06-10 16:13:11 +02:00
Martin Prikryl
1636165e08 Warning when pasting a session URL with unsafe settings
Source commit: a6a8ab80fab4384666d8f4835e7f5fefb91c4aa9
2026-06-10 16:10:38 +02:00
Martin Prikryl
3a2f4913c6 Merging DefaultsOnly and ProtocolDefined parameters
Source commit: 0d19541f3856ea463616237e3df15d99c721ad5d
2026-06-10 01:40:13 +02:00
Martin Prikryl
9bc1aa6d97 Issue 2444 – Avoid using SSH_FXF_EXCL together with SSH_FXF_TRUNC SFTP file opening flags
https://winscp.net/tracker/2444

Source commit: 3a34098adf3a7f0d6307d0d9dfc8b9c1087ef540
2026-06-10 01:35:48 +02:00
Martin Prikryl
cc81f2c3fc Updating code to PuTTY 0.84
Source commit: 71b0bdd5bb7ff22e916234fffeedf5db87668460
2026-05-30 01:07:44 +02:00
Martin Prikryl
5a8c4cdaea Using "username" and "hostname" as one word
Source commit: d86c0d6704a14fff6e3dca57868548df1f80cdd7
2026-05-29 01:15:26 +02:00
Martin Prikryl
c4e2c62171 Using variable as intended
Source commit: d953165a17474e276e54dcc5505ba28867275cf1
2026-05-29 00:51:38 +02:00
Martin Prikryl
941ce4e50e Issue 2440 – When opening session in PuTTY to a host for which WinSCP has multiple hostkeys cached, use the last key or the key that PuTTY has cached
https://winscp.net/tracker/2440

Source commit: 7a596711a8c49cb70687679fe72aec92159ddf6e
2026-05-19 00:59:46 +02:00
Martin Prikryl
327d867495 Issue 2437 – Configurable warning when opening large file in an internal editor
https://winscp.net/tracker/2437

Source commit: 74bdbd0d32c1416c24f384dfc02cc257cc68da14
2026-05-13 01:11:17 +02:00
Martin Prikryl
d725f98ec4 Issue 618 – Experimental 64-bit version of WinSCP
https://winscp.net/tracker/618

Source commit: 329fb51d696db6c1d37d5c5240ff253af0df941b
2026-05-11 18:39:51 +02:00
Martin Prikryl
a1589d1d56 Reading all system settings from 64-bit registry and explicitly using 32-bit registry for own settings for forward compatibility with future 64-bit build
https://winscp.net/tracker/618

Source commit: 752a9de02690c8b6444bea0eb333bab8a3051ee0
2026-04-25 11:43:53 +02:00
Martin Prikryl
17e9b96fac Refactoring
Source commit: 81ebf92fcad32efbe622f753af7c32b554b8fce1
2026-04-22 07:33:56 +02:00
Martin Prikryl
3806702eb1 Unused declaration (since 5cba2a56)
Source commit: b4ed3482bff116d4949419ebd52787afc7a777b7
2026-04-10 01:15:33 +02:00
Martin Prikryl
69ea522611 Reusing EncodeStrToBase64
Source commit: e31dd55472dcec1eae8fee52c3c6c19247fd2446
2026-04-10 01:12:59 +02:00