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:
@@ -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();
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -300,6 +300,7 @@ private:
|
||||
bool FFileTransferAny;
|
||||
bool FLoggedIn;
|
||||
bool FVmsAllRevisions;
|
||||
bool FForceReadSymlink;
|
||||
mutable UnicodeString FOptionScratch;
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user