mirror of
https://github.com/winscp/winscp.git
synced 2026-10-24 02:28:55 +03:00
Bug 1959: Cannot enter an S3 folder that only contains a subfolder with an empty name
https://winscp.net/tracker/1959
(cherry picked from commit b5da4a17fb)
# Conflicts:
# source/core/S3FileSystem.cpp
Source commit: 3a43413dfe2a7542631e7a64b5584d2565a9af47
This commit is contained in:
@@ -463,6 +463,7 @@ struct TLibS3BucketContext : S3BucketContext
|
||||
struct TLibS3ListBucketCallbackData : TLibS3CallbackData
|
||||
{
|
||||
TRemoteFileList * FileList;
|
||||
bool Any;
|
||||
int KeyCount;
|
||||
UTF8String NextMarker;
|
||||
bool IsTruncated;
|
||||
@@ -809,6 +810,7 @@ S3Status TS3FileSystem::LibS3ListBucketCallback(
|
||||
|
||||
for (int Index = 0; Index < ContentsCount; Index++)
|
||||
{
|
||||
Data.Any = true;
|
||||
const S3ListBucketContent * Content = &Contents[Index];
|
||||
UnicodeString FileName = UnixExtractFileName(StrFromS3(Content->key));
|
||||
if (!FileName.IsEmpty())
|
||||
@@ -822,15 +824,11 @@ S3Status TS3FileSystem::LibS3ListBucketCallback(
|
||||
File->Owner = Data.FileSystem->MakeRemoteToken(Content->ownerId, Content->ownerDisplayName);
|
||||
Data.FileList->AddFile(File.release());
|
||||
}
|
||||
else
|
||||
{
|
||||
// We needs this to distinguish empty and non-existing folders, see comments in ReadDirectoryInternal.
|
||||
Data.FileList->AddFile(new TRemoteParentDirectory(Data.FileSystem->FTerminal));
|
||||
}
|
||||
}
|
||||
|
||||
for (int Index = 0; Index < CommonPrefixesCount; Index++)
|
||||
{
|
||||
Data.Any = true;
|
||||
UnicodeString CommonPrefix = StrFromS3(CommonPrefixes[Index]);
|
||||
UnicodeString FileName = UnixExtractFileName(UnixExcludeTrailingBackslash(CommonPrefix));
|
||||
// Have seen prefixes like "/" or "path/subpath//"
|
||||
@@ -854,6 +852,7 @@ void TS3FileSystem::DoListBucket(
|
||||
{
|
||||
S3ListBucketHandler ListBucketHandler = { CreateResponseHandler(), &LibS3ListBucketCallback };
|
||||
RequestInit(Data);
|
||||
Data.Any = false;
|
||||
Data.KeyCount = 0;
|
||||
Data.FileList = FileList;
|
||||
Data.IsTruncated = false;
|
||||
@@ -953,17 +952,18 @@ void TS3FileSystem::ReadDirectoryInternal(
|
||||
} while (Continue);
|
||||
|
||||
// Listing bucket root directory will report an error if the bucket does not exist.
|
||||
// But there won't be any prefix/ entry, so no ".." entry is created, so we have to add it explicitly
|
||||
if (Prefix.IsEmpty())
|
||||
// But there won't be any prefix/ entry, so if the bucket is ampty, the Data.Any is false.
|
||||
// But when listing a prefix, we do not get any error, when the "prefix" does not exist.
|
||||
// But when the prefix does exist, there's at least the prefix/ entry. If there's none, it means that the path does not exist.
|
||||
// Even an empty-named entry/subprefix (which are ignored for other purposes) still indicate that the prefix exists.
|
||||
if (Prefix.IsEmpty() || Data.Any)
|
||||
{
|
||||
FileList->AddFile(new TRemoteParentDirectory(FTerminal));
|
||||
}
|
||||
else
|
||||
{
|
||||
// We do not get any error, when the "prefix" does not exist. But when prefix does exist, there's at least
|
||||
// prefix/ entry (translated to ..). If there's none, it means that the path does not exist.
|
||||
// When called from DoReadFile (FileName is set), leaving error handling to the caller.
|
||||
if ((FileList->Count == 0) && FileName.IsEmpty())
|
||||
if (FileName.IsEmpty())
|
||||
{
|
||||
throw Exception(FMTLOAD(FILE_NOT_EXISTS, (APath)));
|
||||
}
|
||||
@@ -1021,10 +1021,10 @@ void __fastcall TS3FileSystem::DeleteFile(const UnicodeString AFileName,
|
||||
UnicodeString BucketName, Key;
|
||||
ParsePath(FileName, BucketName, Key);
|
||||
|
||||
if (!Key.IsEmpty() && Dir)
|
||||
{
|
||||
Key = GetFolderKey(Key);
|
||||
}
|
||||
if (!Key.IsEmpty() && Dir)
|
||||
{
|
||||
Key = GetFolderKey(Key);
|
||||
}
|
||||
|
||||
TLibS3BucketContext BucketContext = GetBucketContext(BucketName, Key);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user