Quellcode durchsuchen

Issue 2237 – Multipart upload to Cloudflare R2 S3 interface fails due to too long upload ID

https://winscp.net/tracker/2237

Source commit: 01b5fa762fbe00c53104ef9d0d4787d52ba15a40
Martin Prikryl vor 1 Jahr
Ursprung
Commit
7c2a33e79a
3 geänderte Dateien mit 13 neuen und 8 gelöschten Zeilen
  1. 1 0
      libs/libs3/inc/libs3.h
  2. 3 3
      libs/libs3/src/general.c
  3. 9 5
      libs/libs3/src/multipart.c

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

@@ -317,6 +317,7 @@ typedef enum
     S3StatusConnectionFailed                                ,
     S3StatusAbortedByCallback                               ,
     S3StatusNotSupported                                    ,
+    S3StatusUploadIdTooLong                                 , // WINSCP
 
     /**
      * Errors from the S3 service

+ 3 - 3
libs/libs3/src/general.c

@@ -114,6 +114,7 @@ const char *S3_get_status_name(S3Status status)
         handlecase(ConnectionFailed);
         handlecase(AbortedByCallback);
         handlecase(NotSupported);
+        handlecase(UploadIdTooLong);
         handlecase(ErrorAccessDenied);
         handlecase(ErrorAccountProblem);
         handlecase(ErrorAmbiguousGrantByEmailAddress);
@@ -503,15 +504,14 @@ int snprintf_S(char * s, size_t n, const char * format, size_t len, const char *
     int result;
     if (strcmp(format, "%.*s") == 0)
     {
-        result = 0;
-        while ((n > 0) && (len > 0) && (*data != '\0'))
+        result = len;
+        while ((n > 1) && (len > 0) && (*data != '\0'))
         {
             *s = *data;
             ++s;
             ++data;
             --len;
             --n;
-            ++result;
         }
 
         if (n > 0)

+ 9 - 5
libs/libs3/src/multipart.c

@@ -42,7 +42,7 @@ typedef struct InitialMultipartData
     SimpleXml simpleXml;
     int len;
     S3MultipartInitialHandler *handler;
-    string_buffer(upload_id, 256);
+    string_buffer(upload_id, 512);
     void *userdata;
 } InitialMultipartData;
 
@@ -95,6 +95,10 @@ static S3Status initialMultipartXmlCallback(const char *elementPath,
     if (data) {
         if (!strcmp(elementPath, "InitiateMultipartUploadResult/UploadId")) {
             string_buffer_append(mdata->upload_id,data, dataLen, fit);
+            if (!fit) // WINSCP
+            {
+                return S3StatusUploadIdTooLong;
+            }
         }
     }
 
@@ -215,8 +219,8 @@ void S3_upload_part(S3BucketContext *bucketContext, const char *key,
                     int timeoutMs,
                     void *callbackData)
 {
-    char queryParams[512];
-    snprintf(queryParams, 512, "partNumber=%d&uploadId=%s", seq, upload_id);
+    char queryParams[1024];
+    snprintf(queryParams, 1024, "partNumber=%d&uploadId=%s", seq, upload_id);
 
     RequestParams params =
     {
@@ -346,8 +350,8 @@ void S3_complete_multipart_upload(S3BucketContext *bucketContext,
                                   int timeoutMs,
                                   void *callbackData)
 {
-    char queryParams[512];
-    snprintf(queryParams, 512, "uploadId=%s", upload_id);
+    char queryParams[1024];
+    snprintf(queryParams, 1024, "uploadId=%s", upload_id);
     CommitMultiPartData *data =
         (CommitMultiPartData *) malloc(sizeof(CommitMultiPartData));
     data->userdata = callbackData;