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);
