Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package aws-c-s3 for openSUSE:Factory 
checked in at 2026-04-29 19:20:38
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/aws-c-s3 (Old)
 and      /work/SRC/openSUSE:Factory/.aws-c-s3.new.30200 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "aws-c-s3"

Wed Apr 29 19:20:38 2026 rev:39 rq:1350007 version:0.12.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/aws-c-s3/aws-c-s3.changes        2026-04-11 
22:32:33.083549369 +0200
+++ /work/SRC/openSUSE:Factory/.aws-c-s3.new.30200/aws-c-s3.changes     
2026-04-29 19:22:18.540052881 +0200
@@ -1,0 +2,6 @@
+Tue Apr 28 07:46:20 UTC 2026 - John Paul Adrian Glaubitz 
<[email protected]>
+
+- Update to version 0.12.3
+  * Fix recognition of user provided unknown checksums by @DmitriyMusatkin in 
(#624)
+
+-------------------------------------------------------------------

Old:
----
  v0.12.2.tar.gz

New:
----
  v0.12.3.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ aws-c-s3.spec ++++++
--- /var/tmp/diff_new_pack.UN4mmU/_old  2026-04-29 19:22:19.300083989 +0200
+++ /var/tmp/diff_new_pack.UN4mmU/_new  2026-04-29 19:22:19.304084152 +0200
@@ -19,7 +19,7 @@
 %define library_version 1.0.0
 %define library_soversion 0unstable
 Name:           aws-c-s3
-Version:        0.12.2
+Version:        0.12.3
 Release:        0
 Summary:        AWS Cross-Platform, C99 wrapper for cryptography primitives
 License:        Apache-2.0

++++++ v0.12.2.tar.gz -> v0.12.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/aws-c-s3-0.12.2/include/aws/s3/private/s3_checksums.h 
new/aws-c-s3-0.12.3/include/aws/s3/private/s3_checksums.h
--- old/aws-c-s3-0.12.2/include/aws/s3/private/s3_checksums.h   2026-04-02 
20:58:10.000000000 +0200
+++ new/aws-c-s3-0.12.3/include/aws/s3/private/s3_checksums.h   2026-04-24 
22:12:18.000000000 +0200
@@ -56,6 +56,7 @@
 
     enum aws_s3_checksum_location location;
     enum aws_s3_checksum_algorithm checksum_algorithm;
+    struct aws_byte_buf unknown_checksum_algo; /* if checksum algo is unknown 
this will have checksum name */
     bool validate_response_checksum;
     struct {
         bool crc64nvme;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/aws-c-s3-0.12.2/include/aws/s3/private/s3_request_messages.h 
new/aws-c-s3-0.12.3/include/aws/s3/private/s3_request_messages.h
--- old/aws-c-s3-0.12.2/include/aws/s3/private/s3_request_messages.h    
2026-04-02 20:58:10.000000000 +0200
+++ new/aws-c-s3-0.12.3/include/aws/s3/private/s3_request_messages.h    
2026-04-24 22:12:18.000000000 +0200
@@ -36,7 +36,8 @@
     struct aws_http_message *message,
     const struct aws_byte_cursor *excluded_headers_arrays,
     size_t excluded_headers_size,
-    bool exclude_x_amz_meta);
+    bool exclude_x_amz_meta,
+    bool exclude_x_checksum);
 
 /* Copy headers from one message to the other and exclude specific headers.
  * exclude_x_amz_meta controls whether S3 user metadata headers (prefixed with 
"x-amz-meta) are excluded.*/
@@ -46,7 +47,8 @@
     struct aws_http_message *dest_message,
     const struct aws_byte_cursor *excluded_headers_arrays,
     size_t excluded_headers_size,
-    bool exclude_x_amz_meta);
+    bool exclude_x_amz_meta,
+    bool exclude_x_checksum);
 
 AWS_S3_API
 struct aws_input_stream *aws_s3_message_util_assign_body(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aws-c-s3-0.12.2/include/aws/s3/s3_client.h 
new/aws-c-s3-0.12.3/include/aws/s3/s3_client.h
--- old/aws-c-s3-0.12.2/include/aws/s3/s3_client.h      2026-04-02 
20:58:10.000000000 +0200
+++ new/aws-c-s3-0.12.3/include/aws/s3/s3_client.h      2026-04-24 
22:12:18.000000000 +0200
@@ -288,6 +288,7 @@
     AWS_SCA_XXHASH3_64,
     AWS_SCA_XXHASH3_128,
     AWS_SCA_END = AWS_SCA_XXHASH3_128,
+    AWS_SCA_UNKNOWN, /* special value for forwards compat to indicate checksum 
type that crt is not aware of */
 };
 
 enum aws_s3_checksum_location {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aws-c-s3-0.12.2/source/s3_auto_ranged_put.c 
new/aws-c-s3-0.12.3/source/s3_auto_ranged_put.c
--- old/aws-c-s3-0.12.2/source/s3_auto_ranged_put.c     2026-04-02 
20:58:10.000000000 +0200
+++ new/aws-c-s3-0.12.3/source/s3_auto_ranged_put.c     2026-04-24 
22:12:18.000000000 +0200
@@ -957,6 +957,7 @@
             message,
             g_s3_list_parts_excluded_headers,
             g_s3_list_parts_excluded_headers_count,
+            true,
             true);
     } else {
         aws_s3_message_util_copy_headers(
@@ -964,6 +965,7 @@
             message,
             g_s3_list_parts_with_checksum_excluded_headers,
             g_s3_list_parts_with_checksum_excluded_headers_count,
+            true,
             true);
     }
     AWS_ASSERT(message);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aws-c-s3-0.12.2/source/s3_checksums.c 
new/aws-c-s3-0.12.3/source/s3_checksums.c
--- old/aws-c-s3-0.12.2/source/s3_checksums.c   2026-04-02 20:58:10.000000000 
+0200
+++ new/aws-c-s3-0.12.3/source/s3_checksums.c   2026-04-24 22:12:18.000000000 
+0200
@@ -453,6 +453,18 @@
     }
 }
 
+static const struct aws_byte_cursor s_checksum_prefix = 
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-checksum-");
+
+static void s_byte_buf_to_upper(struct aws_byte_buf *buf) {
+    AWS_PRECONDITION(buf);
+
+    for (size_t i = 0; i < buf->len; ++i) {
+        if (buf->buffer[i] >= 'a' && buf->buffer[i] <= 'z') {
+            buf->buffer[i] = buf->buffer[i] + ('A' - 'a');
+        }
+    }
+}
+
 static int s_init_and_verify_checksum_config_from_headers(
     struct aws_s3_meta_request_checksum_config_storage *checksum_config,
     const struct aws_http_message *message,
@@ -463,34 +475,63 @@
     struct aws_byte_cursor header_value;
     AWS_ZERO_STRUCT(header_value);
 
-    for (size_t i = 0; i < AWS_ARRAY_SIZE(s_checksum_algo_priority_list); i++) 
{
-        enum aws_s3_checksum_algorithm algorithm = 
s_checksum_algo_priority_list[i];
-        const struct aws_byte_cursor algorithm_header_name =
-            aws_get_http_header_name_from_checksum_algorithm(algorithm);
-        if (aws_http_headers_get(headers, algorithm_header_name, 
&header_value) == AWS_OP_SUCCESS) {
-            if (header_algo == AWS_SCA_NONE) {
-                header_algo = algorithm;
-            } else {
-                /* If there are multiple checksum headers set, it's malformed 
request */
-                AWS_LOGF_ERROR(
-                    AWS_LS_S3_META_REQUEST,
-                    "id=%p Could not create auto-ranged-put meta request; 
multiple checksum headers has been set",
-                    log_id);
-                return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
+    /*
+     * We want to detect if there are any checksum headers, whether known or 
unknown.
+     * Current approach first looks for any header that starts with 
x-amz-checksum and then
+     * if it finds one, it checks whether it maps to any known checksum 
headers.
+     * if not then we mark checksum as unknown.
+     */
+    bool has_checksum_value_header = false;
+    struct aws_byte_cursor checksum_header_name;
+    for (size_t i = 0; i < aws_http_headers_count(headers); ++i) {
+        struct aws_http_header header;
+        if (aws_http_headers_get_index(headers, i, &header)) {
+            return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
+        }
+
+        if (aws_byte_cursor_starts_with_ignore_case(&header.name, 
&s_checksum_prefix)) {
+            checksum_header_name = header.name;
+            has_checksum_value_header = true;
+            break;
+        }
+    }
+
+    if (has_checksum_value_header) {
+        for (size_t i = 0; i < AWS_ARRAY_SIZE(s_checksum_algo_priority_list); 
i++) {
+            enum aws_s3_checksum_algorithm algorithm = 
s_checksum_algo_priority_list[i];
+            const struct aws_byte_cursor algorithm_header_name =
+                aws_get_http_header_name_from_checksum_algorithm(algorithm);
+            if (aws_http_headers_get(headers, algorithm_header_name, 
&header_value) == AWS_OP_SUCCESS) {
+                if (header_algo == AWS_SCA_NONE) {
+                    header_algo = algorithm;
+                } else {
+                    /* If there are multiple checksum headers set, it's 
malformed request */
+                    AWS_LOGF_ERROR(
+                        AWS_LS_S3_META_REQUEST,
+                        "id=%p Could not create auto-ranged-put meta request; 
multiple checksum headers has been set",
+                        log_id);
+                    return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
+                }
             }
         }
     }
-    if (header_algo == AWS_SCA_NONE) {
+
+    if (!has_checksum_value_header) {
         /* No checksum header found, done */
         return AWS_OP_SUCCESS;
     }
 
+    if (header_algo == AWS_SCA_NONE) {
+        header_algo = AWS_SCA_UNKNOWN;
+    }
+
     if (checksum_config->has_full_object_checksum) {
         /* If the full object checksum has been set, it's malformed request */
         AWS_LOGF_ERROR(
             AWS_LS_S3_META_REQUEST,
             "id=%p: Could not create auto-ranged-put meta request; full object 
checksum is set from multiple ways.",
             log_id);
+
         return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
     }
 
@@ -509,6 +550,13 @@
      **/
     checksum_config->location = AWS_SCL_NONE;
 
+    if (header_algo == AWS_SCA_UNKNOWN) {
+        aws_byte_cursor_advance(&checksum_header_name, s_checksum_prefix.len);
+        aws_byte_buf_init_copy_from_cursor(
+            &checksum_config->unknown_checksum_algo, 
checksum_config->allocator, checksum_header_name);
+        s_byte_buf_to_upper(&checksum_config->unknown_checksum_algo);
+    }
+
     /* Set full object checksum from the header value. */
     aws_byte_buf_init_copy_from_cursor(
         &checksum_config->full_object_checksum, checksum_config->allocator, 
header_value);
@@ -526,6 +574,8 @@
     /* Zero out the struct and set the allocator regardless. */
     internal_config->allocator = allocator;
 
+    /* Potential improvement here is that right now unless you configure 
checksum (which sdks seem to do),
+      the checksum value in the message is not detected and does not get 
propagated to create/complete */
     if (!config) {
         return AWS_OP_SUCCESS;
     }
@@ -631,4 +681,5 @@
     if (internal_config->has_full_object_checksum) {
         aws_byte_buf_clean_up(&internal_config->full_object_checksum);
     }
+    aws_byte_buf_clean_up(&internal_config->unknown_checksum_algo);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aws-c-s3-0.12.2/source/s3_request_messages.c 
new/aws-c-s3-0.12.3/source/s3_request_messages.c
--- old/aws-c-s3-0.12.2/source/s3_request_messages.c    2026-04-02 
20:58:10.000000000 +0200
+++ new/aws-c-s3-0.12.3/source/s3_request_messages.c    2026-04-24 
22:12:18.000000000 +0200
@@ -22,13 +22,9 @@
     AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Content-MD5"),
     AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-copy-source"),
     AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-copy-source-range"),
-    AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-checksum-crc64nvme"),
-    AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-checksum-crc32c"),
-    AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-checksum-crc32"),
-    AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-checksum-sha1"),
-    AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-checksum-sha256"),
     AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("if-none-match"),
     AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-create-session-mode"),
+    AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-sdk-checksum-algorithm"),
 };
 
 const size_t g_s3_create_multipart_upload_excluded_headers_count =
@@ -58,11 +54,6 @@
     AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-object-lock-mode"),
     
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-object-lock-retain-until-date"),
     AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-object-lock-legal-hold"),
-    AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-checksum-crc64nvme"),
-    AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-checksum-crc32c"),
-    AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-checksum-crc32"),
-    AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-checksum-sha1"),
-    AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-checksum-sha256"),
     AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("if-none-match"),
     AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-create-session-mode"),
 };
@@ -248,6 +239,7 @@
 const size_t g_s3_create_session_allowed_headers_count = 
AWS_ARRAY_SIZE(g_s3_create_session_allowed_headers);
 
 static const struct aws_byte_cursor s_x_amz_meta_prefix = 
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-meta-");
+static const struct aws_byte_cursor s_x_amz_checksum_prefix = 
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-checksum-");
 
 static const struct aws_byte_cursor s_checksum_type_header =
     AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-checksum-type");
@@ -299,7 +291,8 @@
         base_message,
         g_s3_create_multipart_upload_excluded_headers,
         AWS_ARRAY_SIZE(g_s3_create_multipart_upload_excluded_headers),
-        false /*exclude_x_amz_meta*/);
+        false /*exclude_x_amz_meta*/,
+        true /*exclude_x_checksum_meta*/);
 
     if (message == NULL) {
         return NULL;
@@ -322,7 +315,12 @@
     }
 
     if (checksum_config && (checksum_config->location != AWS_SCL_NONE || 
checksum_config->has_full_object_checksum)) {
-        if (checksum_config->checksum_algorithm) {
+        if (checksum_config->checksum_algorithm == AWS_SCA_UNKNOWN) {
+            struct aws_byte_cursor checksum_name = 
aws_byte_cursor_from_buf(&checksum_config->unknown_checksum_algo);
+            if (aws_http_headers_set(headers, 
g_checksum_algorithm_header_name, checksum_name)) {
+                goto error_clean_up;
+            }
+        } else if (checksum_config->checksum_algorithm) {
             if (aws_http_headers_set(
                     headers,
                     g_checksum_algorithm_header_name,
@@ -374,7 +372,8 @@
         base_message,
         g_s3_upload_part_excluded_headers,
         AWS_ARRAY_SIZE(g_s3_upload_part_excluded_headers),
-        true /*exclude_x_amz_meta*/);
+        true /*exclude_x_amz_meta*/,
+        true /*exclude_x_checksum_meta*/);
 
     if (message == NULL) {
         return NULL;
@@ -429,7 +428,8 @@
         base_message,
         g_s3_upload_part_excluded_headers,
         AWS_ARRAY_SIZE(g_s3_upload_part_excluded_headers),
-        true /*exclude_x_amz_meta*/);
+        true /*exclude_x_amz_meta*/,
+        true /*exclude_x_checksum_meta*/);
 
     if (message == NULL) {
         return NULL;
@@ -477,7 +477,8 @@
         base_message,
         g_s3_upload_part_excluded_headers,
         AWS_ARRAY_SIZE(g_s3_upload_part_excluded_headers),
-        true /*exclude_x_amz_meta*/);
+        true /*exclude_x_amz_meta*/,
+        true /*exclude_x_checksum_meta*/);
 
     if (message == NULL) {
         goto error_clean_up;
@@ -706,7 +707,8 @@
             base_message,
             g_s3_complete_multipart_upload_with_checksum_excluded_headers,
             
AWS_ARRAY_SIZE(g_s3_complete_multipart_upload_with_checksum_excluded_headers),
-            true /*exclude_x_amz_meta*/);
+            true /*exclude_x_amz_meta*/,
+            false /*exclude_x_checksum_meta*/);
 
     } else {
         message = aws_s3_message_util_copy_http_message_no_body_filter_headers(
@@ -714,7 +716,8 @@
             base_message,
             g_s3_complete_multipart_upload_excluded_headers,
             AWS_ARRAY_SIZE(g_s3_complete_multipart_upload_excluded_headers),
-            true /*exclude_x_amz_meta*/);
+            true /*exclude_x_amz_meta*/,
+            false /*exclude_x_checksum_meta*/);
     }
 
     struct aws_http_headers *headers = NULL;
@@ -863,7 +866,8 @@
         base_message,
         g_s3_abort_multipart_upload_excluded_headers,
         AWS_ARRAY_SIZE(g_s3_abort_multipart_upload_excluded_headers),
-        true /*exclude_x_amz_meta*/);
+        true /*exclude_x_amz_meta*/,
+        true /*exclude_x_checksum_meta*/);
 
     if (aws_s3_message_util_set_multipart_request_path(allocator, upload_id, 
0, false, message)) {
         goto error_clean_up;
@@ -1141,7 +1145,7 @@
     struct aws_allocator *allocator,
     struct aws_http_message *base_message) {
 
-    return 
aws_s3_message_util_copy_http_message_no_body_filter_headers(allocator, 
base_message, NULL, 0, false);
+    return 
aws_s3_message_util_copy_http_message_no_body_filter_headers(allocator, 
base_message, NULL, 0, false, false);
 }
 
 struct aws_http_message 
*aws_s3_message_util_copy_http_message_no_body_filter_headers(
@@ -1149,7 +1153,8 @@
     struct aws_http_message *base_message,
     const struct aws_byte_cursor *excluded_header_array,
     size_t excluded_header_array_size,
-    bool exclude_x_amz_meta) {
+    bool exclude_x_amz_meta,
+    bool exclude_x_amz_checksum) {
 
     AWS_PRECONDITION(allocator);
     AWS_PRECONDITION(base_message);
@@ -1178,7 +1183,12 @@
     }
 
     aws_s3_message_util_copy_headers(
-        base_message, message, excluded_header_array, 
excluded_header_array_size, exclude_x_amz_meta);
+        base_message,
+        message,
+        excluded_header_array,
+        excluded_header_array_size,
+        exclude_x_amz_meta,
+        exclude_x_amz_checksum);
 
     return message;
 
@@ -1192,7 +1202,8 @@
     struct aws_http_message *dest_message,
     const struct aws_byte_cursor *excluded_header_array,
     size_t excluded_header_array_size,
-    bool exclude_x_amz_meta) {
+    bool exclude_x_amz_meta,
+    bool exclude_x_amz_checksum) {
 
     size_t num_headers = aws_http_message_get_header_count(source_message);
 
@@ -1221,6 +1232,12 @@
                 continue;
             }
         }
+
+        if (exclude_x_amz_checksum) {
+            if (aws_byte_cursor_starts_with_ignore_case(&header.name, 
&s_x_amz_checksum_prefix)) {
+                continue;
+            }
+        }
 
         error |= aws_http_message_add_header(dest_message, header);
         (void)error;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aws-c-s3-0.12.2/tests/CMakeLists.txt 
new/aws-c-s3-0.12.3/tests/CMakeLists.txt
--- old/aws-c-s3-0.12.2/tests/CMakeLists.txt    2026-04-02 20:58:10.000000000 
+0200
+++ new/aws-c-s3-0.12.3/tests/CMakeLists.txt    2026-04-24 22:12:18.000000000 
+0200
@@ -25,6 +25,8 @@
 add_test_case(test_s3_complete_multipart_message_new)
 add_test_case(test_s3_abort_multipart_upload_message_new)
 
+add_net_test_case(test_s3_put_object_custom_md5)
+
 add_net_test_case(test_s3_client_create_destroy)
 add_net_test_case(test_s3_client_create_error)
 add_net_test_case(test_s3_client_create_error_with_invalid_memory_limit_config)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aws-c-s3-0.12.2/tests/s3_data_plane_tests.c 
new/aws-c-s3-0.12.3/tests/s3_data_plane_tests.c
--- old/aws-c-s3-0.12.2/tests/s3_data_plane_tests.c     2026-04-02 
20:58:10.000000000 +0200
+++ new/aws-c-s3-0.12.3/tests/s3_data_plane_tests.c     2026-04-24 
22:12:18.000000000 +0200
@@ -2332,6 +2332,118 @@
     return s_test_s3_put_object_multiple_helper(allocator, true, true);
 }
 
+/*
+ * Helper that simulates the situation where the checksum value is provided in 
the message on put,
+ * but also checksum config is specified.
+ */
+static int s_test_s3_put_object_with_checksum_header_helper(struct 
aws_allocator *allocator) {
+
+    struct aws_s3_meta_request *meta_request;
+    struct aws_s3_meta_request_test_results meta_request_test_result;
+    struct aws_http_message *message;
+    struct aws_input_stream *input_stream;
+    struct aws_byte_buf input_stream_buffer;
+
+    struct aws_s3_tester tester;
+    AWS_ZERO_STRUCT(tester);
+    ASSERT_SUCCESS(aws_s3_tester_init(allocator, &tester));
+
+    struct aws_s3_client_config client_config;
+    AWS_ZERO_STRUCT(client_config);
+
+    ASSERT_SUCCESS(aws_s3_tester_bind_client(
+        &tester, &client_config, AWS_S3_TESTER_BIND_CLIENT_REGION | 
AWS_S3_TESTER_BIND_CLIENT_SIGNING));
+
+    struct aws_s3_client *client = aws_s3_client_new(allocator, 
&client_config);
+
+    struct aws_string *host_name =
+        aws_s3_tester_build_endpoint_string(allocator, &g_test_bucket_name, 
&g_test_s3_region);
+
+    size_t content_length = MB_TO_BYTES(20);
+
+    aws_s3_meta_request_test_results_init(&meta_request_test_result, 
allocator);
+    char object_path_buffer[128] = "";
+    snprintf(
+        object_path_buffer,
+        sizeof(object_path_buffer),
+        "" PRInSTR "-20MB-custom.txt",
+        AWS_BYTE_CURSOR_PRI(g_put_object_prefix));
+    AWS_ZERO_STRUCT(input_stream_buffer);
+    aws_s3_create_test_buffer(allocator, content_length, &input_stream_buffer);
+    struct aws_byte_cursor test_body_cursor = 
aws_byte_cursor_from_buf(&input_stream_buffer);
+    input_stream = aws_input_stream_new_from_cursor(allocator, 
&test_body_cursor);
+    struct aws_byte_cursor test_object_path = 
aws_byte_cursor_from_c_str(object_path_buffer);
+    struct aws_byte_cursor host_cur = aws_byte_cursor_from_string(host_name);
+
+    struct aws_s3_meta_request_options options;
+    AWS_ZERO_STRUCT(options);
+    options.type = AWS_S3_META_REQUEST_TYPE_PUT_OBJECT;
+    message = aws_s3_test_put_object_request_new(
+        allocator, &host_cur, test_object_path, g_test_body_content_type, 
input_stream, 0);
+
+    struct aws_http_header checksum_header = {
+        .name = aws_byte_cursor_from_c_str("x-amz-checksum-md5"),
+        .value = aws_byte_cursor_from_c_str("9Z7oAj6JEFbH2PcvG+6V+w=="),
+    };
+
+    aws_http_message_add_header(message, checksum_header);
+
+    options.message = message;
+    struct aws_s3_checksum_config checksum_config = {
+        .checksum_algorithm = AWS_SCA_CRC32,
+        .location = AWS_SCL_TRAILER,
+    };
+
+    options.checksum_config = &checksum_config;
+
+    ASSERT_SUCCESS(aws_s3_tester_bind_meta_request(&tester, &options, 
&meta_request_test_result));
+
+    meta_request = aws_s3_client_make_meta_request(client, &options);
+
+    ASSERT_TRUE(meta_request != NULL);
+
+    /* Wait for the request to finish. */
+    aws_s3_tester_wait_for_meta_request_finish(&tester);
+
+    aws_s3_tester_lock_synced_data(&tester);
+    ASSERT_TRUE(tester.synced_data.finish_error_code != AWS_OP_SUCCESS);
+
+    aws_s3_tester_unlock_synced_data(&tester);
+
+    meta_request = aws_s3_meta_request_release(meta_request);
+
+    aws_s3_tester_wait_for_meta_request_shutdown(&tester);
+
+    ASSERT_INT_EQUALS(meta_request_test_result.finished_response_status, 400);
+
+    struct aws_byte_cursor body = 
aws_byte_cursor_from_buf(&meta_request_test_result.error_response_body);
+    struct aws_byte_cursor to_find =
+        aws_byte_cursor_from_c_str("The FULL_OBJECT checksum type cannot be 
used with the md5 checksum algorithm");
+    struct aws_byte_cursor result_cur = {0};
+    ASSERT_SUCCESS(aws_byte_cursor_find_exact(&body, &to_find, &result_cur));
+
+    aws_s3_meta_request_test_results_clean_up(&meta_request_test_result);
+
+    aws_http_message_release(message);
+    aws_input_stream_release(input_stream);
+    aws_byte_buf_clean_up(&input_stream_buffer);
+
+    aws_string_destroy(host_name);
+    host_name = NULL;
+
+    client = aws_s3_client_release(client);
+
+    aws_s3_tester_clean_up(&tester);
+
+    return 0;
+}
+
+AWS_TEST_CASE(test_s3_put_object_custom_md5, s_test_s3_put_object_custom_md5)
+static int s_test_s3_put_object_custom_md5(struct aws_allocator *allocator, 
void *ctx) {
+    (void)ctx;
+    return s_test_s3_put_object_with_checksum_header_helper(allocator);
+}
+
 AWS_TEST_CASE(test_s3_put_object_less_than_part_size, 
s_test_s3_put_object_less_than_part_size)
 static int s_test_s3_put_object_less_than_part_size(struct aws_allocator 
*allocator, void *ctx) {
     (void)ctx;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aws-c-s3-0.12.2/tests/s3_request_messages_tests.c 
new/aws-c-s3-0.12.3/tests/s3_request_messages_tests.c
--- old/aws-c-s3-0.12.2/tests/s3_request_messages_tests.c       2026-04-02 
20:58:10.000000000 +0200
+++ new/aws-c-s3-0.12.3/tests/s3_request_messages_tests.c       2026-04-24 
22:12:18.000000000 +0200
@@ -205,6 +205,8 @@
     return AWS_OP_SUCCESS;
 }
 
+static const struct aws_byte_cursor s_x_amz_checksum_prefix = 
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-checksum-");
+
 static int s_test_http_headers_match(
     struct aws_allocator *allocator,
     const struct aws_http_message *message0,
@@ -217,7 +219,8 @@
     /* Headers in message1 that are okay to be in message1 even if they are in 
the excluded list or are not in
        message0.*/
     const struct aws_byte_cursor *message1_header_exceptions,
-    size_t message1_header_exceptions_count) {
+    size_t message1_header_exceptions_count,
+    bool should_exclude_checksum) {
     ASSERT_TRUE(message0 != NULL);
     ASSERT_TRUE(message1 != NULL);
     ASSERT_TRUE(excluded_message0_headers != NULL || 
excluded_message0_headers_count == 0);
@@ -285,6 +288,19 @@
         }
     }
 
+    if (should_exclude_checksum) {
+        /* Copy any checksum headers if they were on exclude list */
+        for (size_t i = 0; i < aws_http_headers_count(message0_headers); ++i) {
+            struct aws_http_header message0_header;
+            AWS_ZERO_STRUCT(message0_header);
+            ASSERT_SUCCESS(aws_http_headers_get_index(message0_headers, i, 
&message0_header));
+            if (aws_byte_cursor_starts_with_ignore_case(&message0_header.name, 
&s_x_amz_checksum_prefix)) {
+                ASSERT_SUCCESS(
+                    aws_http_headers_add(expected_message0_headers, 
message0_header.name, message0_header.value));
+            }
+        }
+    }
+
     /* message0_headers should now match expected_message0_headers */
     {
         ASSERT_TRUE(aws_http_headers_count(message0_headers) == 
aws_http_headers_count(expected_message0_headers));
@@ -313,7 +329,8 @@
     const struct aws_http_message *message0,
     const struct aws_http_message *message1,
     const struct aws_byte_cursor *excluded_headers,
-    size_t excluded_headers_count) {
+    size_t excluded_headers_count,
+    bool should_exclude_checksum) {
     ASSERT_TRUE(message0 != NULL);
     ASSERT_TRUE(message1 != NULL);
     ASSERT_TRUE(excluded_headers != NULL || excluded_headers_count == 0);
@@ -338,8 +355,8 @@
 
     ASSERT_TRUE(aws_byte_cursor_eq(&request_method, &copied_request_method));
 
-    ASSERT_SUCCESS(
-        s_test_http_headers_match(allocator, message0, message1, 
excluded_headers, excluded_headers_count, NULL, 0));
+    ASSERT_SUCCESS(s_test_http_headers_match(
+        allocator, message0, message1, excluded_headers, 
excluded_headers_count, NULL, 0, should_exclude_checksum));
 
     return AWS_OP_SUCCESS;
 }
@@ -483,18 +500,28 @@
 
     { /* copy message, include "x-amz-meta-" */
         struct aws_http_message *copied_message = 
aws_s3_message_util_copy_http_message_no_body_filter_headers(
-            allocator, message, excluded_headers, 
AWS_ARRAY_SIZE(excluded_headers), false /*exclude_x_amz_meta*/);
+            allocator,
+            message,
+            excluded_headers,
+            AWS_ARRAY_SIZE(excluded_headers),
+            false /*exclude_x_amz_meta*/,
+            true /*exclude_x_amz_checksum*/);
         ASSERT_TRUE(copied_message != NULL);
 
         ASSERT_SUCCESS(s_test_http_messages_match(
-            allocator, message, copied_message, excluded_headers, 
AWS_ARRAY_SIZE(excluded_headers)));
+            allocator, message, copied_message, excluded_headers, 
AWS_ARRAY_SIZE(excluded_headers), true));
 
         aws_http_message_release(copied_message);
     }
 
     { /* copy message, exclude "x-amz-meta-" */
         struct aws_http_message *copied_message = 
aws_s3_message_util_copy_http_message_no_body_filter_headers(
-            allocator, message, excluded_headers, 
AWS_ARRAY_SIZE(excluded_headers), true /*exclude_x_amz_meta*/);
+            allocator,
+            message,
+            excluded_headers,
+            AWS_ARRAY_SIZE(excluded_headers),
+            true /*exclude_x_amz_meta*/,
+            true /*exclude_x_amz_checksum*/);
         ASSERT_TRUE(copied_message != NULL);
 
         const struct aws_byte_cursor expected_excluded_headers[] = {
@@ -503,7 +530,12 @@
         };
 
         ASSERT_SUCCESS(s_test_http_messages_match(
-            allocator, message, copied_message, expected_excluded_headers, 
AWS_ARRAY_SIZE(expected_excluded_headers)));
+            allocator,
+            message,
+            copied_message,
+            expected_excluded_headers,
+            AWS_ARRAY_SIZE(expected_excluded_headers),
+            true));
 
         aws_http_message_release(copied_message);
     }
@@ -695,7 +727,8 @@
         g_s3_create_multipart_upload_excluded_headers,
         g_s3_create_multipart_upload_excluded_headers_count,
         header_exclude_exceptions,
-        AWS_ARRAY_SIZE(header_exclude_exceptions)));
+        AWS_ARRAY_SIZE(header_exclude_exceptions),
+        true));
 
     aws_http_message_release(create_multipart_upload_message);
     aws_http_message_release(original_message);
@@ -746,7 +779,8 @@
         g_s3_upload_part_excluded_headers,
         g_s3_upload_part_excluded_headers_count,
         header_exclude_exceptions,
-        AWS_ARRAY_SIZE(header_exclude_exceptions)));
+        AWS_ARRAY_SIZE(header_exclude_exceptions),
+        true));
 
     ASSERT_SUCCESS(s_test_http_message_body_stream(allocator, 
upload_part_message, &part_buffer));
 
@@ -893,7 +927,8 @@
         g_s3_complete_multipart_upload_excluded_headers,
         g_s3_complete_multipart_upload_excluded_headers_count,
         header_exclude_exceptions,
-        AWS_ARRAY_SIZE(header_exclude_exceptions)));
+        AWS_ARRAY_SIZE(header_exclude_exceptions),
+        false));
 
     {
         struct complete_multipart_upload_xml_test_data xml_user_data = {
@@ -961,7 +996,8 @@
         g_s3_abort_multipart_upload_excluded_headers,
         g_s3_abort_multipart_upload_excluded_headers_count,
         NULL,
-        0));
+        0,
+        true));
 
     aws_string_destroy(upload_id);
 

Reply via email to