瀏覽代碼

Bug fix: Timezone is not correctly reflected in S3 timestamps

(cherry picked from commit 5ef25f17843ab365db79c17997b510ebfb41400a)

Source commit: fbe3c1f49112faa5daf9a81abca6cf033278cf91
Martin Prikryl 4 年之前
父節點
當前提交
1316cd0247
共有 4 個文件被更改,包括 37 次插入1 次删除
  1. 1 0
      libs/libs3/inc/libs3.h
  2. 1 0
      libs/libs3/src/bucket.c
  3. 26 1
      source/core/S3FileSystem.cpp
  4. 9 0
      source/core/WebDAVFileSystem.cpp

+ 1 - 0
libs/libs3/inc/libs3.h

@@ -767,6 +767,7 @@ typedef struct S3ListBucketContent
      * date of the object identified by the key.
      **/
     int64_t lastModified;
+    const char *lastModifiedStr; // WINSCP 
 
     /**
      * This gives a tag which gives a signature of the contents of the object,

+ 1 - 0
libs/libs3/src/bucket.c

@@ -493,6 +493,7 @@ static S3Status make_list_bucket_callback(ListBucketData *lbData)
         contentDest->key = contentSrc->key;
         contentDest->lastModified =
             parseIso8601Time(contentSrc->lastModified);
+        contentDest->lastModifiedStr = contentSrc->lastModified; // WINSCP
         contentDest->eTag = contentSrc->eTag;
         contentDest->size = parseUnsignedInt(contentSrc->size);
         contentDest->ownerId =

+ 26 - 1
source/core/S3FileSystem.cpp

@@ -819,7 +819,32 @@ S3Status TS3FileSystem::LibS3ListBucketCallback(
       File->Terminal = Data.FileSystem->FTerminal;
       File->FileName = FileName;
       File->Type = FILETYPE_DEFAULT;
-      File->Modification = UnixToDateTime(Content->lastModified, dstmWin);
+
+      #define ISO8601_FORMAT "%04d-%02d-%02dT%02d:%02d:%02d"
+      int Year = 0;
+      int Month = 0;
+      int Day = 0;
+      int Hour = 0;
+      int Min = 0;
+      int Sec = 0;
+      // The libs3's parseIso8601Time uses mktime, so returns a local time, which we would have to complicatedly restore,
+      // Doing own parting instead as it's easier.
+      // Keep is sync with WebDAV
+      int Filled =
+        sscanf(Content->lastModifiedStr, ISO8601_FORMAT, &Year, &Month, &Day, &Hour, &Min, &Sec);
+      if (Filled == 6)
+      {
+        TDateTime Modification =
+          EncodeDateVerbose((unsigned short)Year, (unsigned short)Month, (unsigned short)Day) +
+          EncodeTimeVerbose((unsigned short)Hour, (unsigned short)Min, (unsigned short)Sec, 0);
+        File->Modification = ConvertTimestampFromUTC(Modification);
+        File->ModificationFmt = mfFull;
+      }
+      else
+      {
+        File->ModificationFmt = mfNone;
+      }
+
       File->Size = Content->size;
       File->Owner = Data.FileSystem->MakeRemoteToken(Content->ownerId, Content->ownerDisplayName);
       Data.FileList->AddFile(File.release());

+ 9 - 0
source/core/WebDAVFileSystem.cpp

@@ -859,6 +859,7 @@ void __fastcall TWebDAVFileSystem::ParsePropResultSet(TRemoteFile * File,
     int Min = 0;
     int Sec = 0;
     #define RFC1123_FORMAT "%3s, %02d %3s %4d %02d:%02d:%02d GMT"
+    // Keep is sync with S3
     int Filled =
       sscanf(LastModified, RFC1123_FORMAT, WeekDay, &Day, MonthStr, &Year, &Hour, &Min, &Sec);
     // we need at least a complete date
@@ -873,6 +874,14 @@ void __fastcall TWebDAVFileSystem::ParsePropResultSet(TRemoteFile * File,
         File->Modification = ConvertTimestampFromUTC(Modification);
         File->ModificationFmt = mfFull;
       }
+      else
+      {
+        File->ModificationFmt = mfNone;
+      }
+    }
+    else
+    {
+      File->ModificationFmt = mfNone;
     }
   }