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

Bug 1973: Allow downloading a file from an FTP server via a symbolic link in scripting or when handling a URL

https://winscp.net/tracker/1973
(cherry picked from commit c322ad84e8)

# Conflicts:
#	source/core/FtpFileSystem.h

Source commit: 741b7ef4e6b74ab6c4f8556ff50a6d333c1e23a6
This commit is contained in:
Martin Prikryl
2021-04-08 12:06:57 +00:00
parent 8ff4d2edb5
commit 6c6f5ed190
2 changed files with 25 additions and 14 deletions

View File

@@ -272,6 +272,7 @@ __fastcall TFTPFileSystem::TFTPFileSystem(TTerminal * ATerminal):
FBytesAvailableSuppoted = false;
FLoggedIn = false;
FAnyTransferSucceeded = false; // Do not reset on reconnect
FForceReadSymlink = false;
FChecksumAlgs.reset(new TStringList());
FChecksumCommands.reset(new TStringList());
@@ -2440,6 +2441,7 @@ void __fastcall TFTPFileSystem::ReadFile(const UnicodeString FileName,
AFile = FFileListCache->FindFile(NameOnly);
}
VMSAllRevisionsFlag.Release();
if (AFile != NULL)
{
@@ -2449,6 +2451,11 @@ void __fastcall TFTPFileSystem::ReadFile(const UnicodeString FileName,
File->FileName = FileName;
File->FullFileName = FileName;
}
if (File->IsSymLink)
{
TAutoFlag AutoFlag(FForceReadSymlink);
File->Complete();
}
}
}
}
@@ -2462,23 +2469,26 @@ void __fastcall TFTPFileSystem::ReadFile(const UnicodeString FileName,
void __fastcall TFTPFileSystem::ReadSymlink(TRemoteFile * SymlinkFile,
TRemoteFile *& File)
{
// Resolving symlinks over FTP is big overhead
// (involves opening TCPIP connection for retrieving "directory listing").
// Moreover FZAPI does not support that anyway.
// Though nowadays we could use MLST to read the symlink.
File = new TRemoteFile(SymlinkFile);
try
if (FForceReadSymlink && DebugAlwaysTrue(!SymlinkFile->LinkTo.IsEmpty()) && DebugAlwaysTrue(SymlinkFile->HaveFullFileName))
{
File->Terminal = FTerminal;
File->FileName = UnixExtractFileName(SymlinkFile->LinkTo);
// FZAPI treats all symlink target as directories
File->Type = FILETYPE_DIRECTORY;
// When we get here from TFTPFileSystem::ReadFile, it's likely the second time ReadSymlink has been called for the link.
// The first time getting to the later branch, so IsDirectory is true and hence FullFileName ends with a slash.
UnicodeString SymlinkDir = UnixExtractFileDir(UnixExcludeTrailingBackslash(SymlinkFile->FullFileName));
UnicodeString LinkTo = ::AbsolutePath(SymlinkDir, SymlinkFile->LinkTo);
ReadFile(LinkTo, File);
}
catch(...)
else
{
delete File;
File = NULL;
throw;
// Resolving symlinks over FTP is big overhead
// (involves opening TCPIP connection for retrieving "directory listing").
// Moreover FZAPI does not support that anyway.
// Though nowadays we could use MLST to read the symlink.
std::unique_ptr<TRemoteFile> AFile(new TRemoteFile(SymlinkFile));
AFile->Terminal = FTerminal;
AFile->FileName = UnixExtractFileName(SymlinkFile->LinkTo);
// FZAPI treats all symlink target as directories
AFile->Type = FILETYPE_DIRECTORY;
File = AFile.release();
}
}
//---------------------------------------------------------------------------

View File

@@ -300,6 +300,7 @@ private:
bool FFileTransferAny;
bool FLoggedIn;
bool FVmsAllRevisions;
bool FForceReadSymlink;
mutable UnicodeString FOptionScratch;
};
//---------------------------------------------------------------------------