Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package aws-c-http for openSUSE:Factory checked in at 2026-05-26 16:35:05 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/aws-c-http (Old) and /work/SRC/openSUSE:Factory/.aws-c-http.new.2084 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "aws-c-http" Tue May 26 16:35:05 2026 rev:28 rq:1355154 version:0.11.0 Changes: -------- --- /work/SRC/openSUSE:Factory/aws-c-http/aws-c-http.changes 2026-04-09 16:25:00.351156534 +0200 +++ /work/SRC/openSUSE:Factory/.aws-c-http.new.2084/aws-c-http.changes 2026-05-26 16:35:20.891264223 +0200 @@ -1,0 +2,9 @@ +Fri May 22 07:41:41 UTC 2026 - John Paul Adrian Glaubitz <[email protected]> + +- Update to 0.11.0 + * Fix rounding error in hpack resizing by @DmitriyMusatkin in (#559) +- from version 0.10.15 + * builder -> v0.9.92 and clang-latest by @sbSteveK in (#557) + * [fix] h2 double complete by @TingDaoK in (#558) + +------------------------------------------------------------------- Old: ---- v0.10.14.tar.gz New: ---- v0.11.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ aws-c-http.spec ++++++ --- /var/tmp/diff_new_pack.ZCusXi/_old 2026-05-26 16:35:21.535290867 +0200 +++ /var/tmp/diff_new_pack.ZCusXi/_new 2026-05-26 16:35:21.535290867 +0200 @@ -20,7 +20,7 @@ %define library_version 1.0.0 %define library_soversion 1_0_0 Name: aws-c-http -Version: 0.10.14 +Version: 0.11.0 Release: 0 Summary: C99 implementation of the HTTP/1.1 and HTTP/2 specifications License: Apache-2.0 ++++++ v0.10.14.tar.gz -> v0.11.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-http-0.10.14/.github/workflows/ci.yml new/aws-c-http-0.11.0/.github/workflows/ci.yml --- old/aws-c-http-0.10.14/.github/workflows/ci.yml 2026-03-31 22:04:47.000000000 +0200 +++ new/aws-c-http-0.11.0/.github/workflows/ci.yml 2026-05-21 22:22:41.000000000 +0200 @@ -6,7 +6,7 @@ - 'main' env: - BUILDER_VERSION: v0.9.90 + BUILDER_VERSION: v0.9.92 BUILDER_SOURCE: releases BUILDER_HOST: https://d19elf31gohf1l.cloudfront.net PACKAGE_NAME: aws-c-http @@ -56,6 +56,7 @@ - name: clang-11 - name: clang-15 - name: clang-17 + - name: clang-latest - name: gcc-4.8 - name: gcc-5 - name: gcc-6 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-http-0.10.14/include/aws/http/private/h2_stream.h new/aws-c-http-0.11.0/include/aws/http/private/h2_stream.h --- old/aws-c-http-0.10.14/include/aws/http/private/h2_stream.h 2026-03-31 22:04:47.000000000 +0200 +++ new/aws-c-http-0.11.0/include/aws/http/private/h2_stream.h 2026-05-21 22:22:41.000000000 +0200 @@ -118,6 +118,9 @@ * asleep. When stream needs to be awaken, moving the stream back to the outgoing_streams_list and set this bool * to false */ bool waiting_for_writes; + /* Set when s_stream_complete has been called. Prevents double-completion + * (e.g. GOAWAY completes stream, then pending cancel cross-thread task fires) */ + bool is_complete; } thread_data; /* Any thread may touch this data, but the lock must be held (unless it's an atomic) */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-http-0.10.14/source/h2_connection.c new/aws-c-http-0.11.0/source/h2_connection.c --- old/aws-c-http-0.10.14/source/h2_connection.c 2026-03-31 22:04:47.000000000 +0200 +++ new/aws-c-http-0.11.0/source/h2_connection.c 2026-05-21 22:22:41.000000000 +0200 @@ -1868,6 +1868,13 @@ static void s_stream_complete(struct aws_h2_connection *connection, struct aws_h2_stream *stream, int error_code) { AWS_PRECONDITION(aws_channel_thread_is_callers_thread(connection->base.channel_slot->channel)); + /* Guard against double-completion (e.g. GOAWAY completes stream, then pending cancel task fires) */ + if (stream->thread_data.is_complete) { + AWS_H2_STREAM_LOG(DEBUG, stream, "stream already completed, ignoring."); + return; + } + stream->thread_data.is_complete = true; + /* Nice logging */ if (error_code) { AWS_H2_STREAM_LOGF( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-http-0.10.14/source/hpack.c new/aws-c-http-0.11.0/source/hpack.c --- old/aws-c-http-0.10.14/source/hpack.c 2026-03-31 22:04:47.000000000 +0200 +++ new/aws-c-http-0.11.0/source/hpack.c 2026-05-21 22:22:41.000000000 +0200 @@ -14,9 +14,6 @@ /* TODO: shouldn't be a hardcoded max_size, it should be driven by SETTINGS_HEADER_TABLE_SIZE */ const size_t s_hpack_dynamic_table_max_size = 16 * 1024 * 1024; -/* Used for growing the dynamic table buffer when it fills up */ -const float s_hpack_dynamic_table_buffer_growth_rate = 1.5F; - struct aws_http_header s_static_header_table[] = { #define HEADER(_index, _name) \ [_index] = { \ @@ -421,7 +418,8 @@ /* If the buffer is currently of 0 size, reset it back to its initial size */ const size_t new_size = context->dynamic_table.buffer_capacity - ? (size_t)(context->dynamic_table.buffer_capacity * s_hpack_dynamic_table_buffer_growth_rate) + /* increase buffer by 1.5 rounded up. */ + ? (size_t)(context->dynamic_table.buffer_capacity + ((context->dynamic_table.buffer_capacity + 1) / 2)) : s_hpack_dynamic_table_initial_elements; if (s_dynamic_table_resize_buffer(context, new_size)) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-http-0.10.14/tests/CMakeLists.txt new/aws-c-http-0.11.0/tests/CMakeLists.txt --- old/aws-c-http-0.10.14/tests/CMakeLists.txt 2026-03-31 22:04:47.000000000 +0200 +++ new/aws-c-http-0.11.0/tests/CMakeLists.txt 2026-05-21 22:22:41.000000000 +0200 @@ -297,6 +297,7 @@ add_test_case(hpack_decode_indexed_from_dynamic_table) add_test_case(hpack_dynamic_table_empty_value) add_test_case(hpack_dynamic_table_with_empty_header) +add_test_case(hpack_dynamic_table_growth_corner_case) add_test_case(hpack_dynamic_table_size_update_from_setting) if(ENABLE_LOCALHOST_INTEGRATION_TESTS) @@ -712,6 +713,7 @@ add_net_test_case(h2_sm_mock_ideal_num_streams) add_net_test_case(h2_sm_mock_large_ideal_num_streams) add_net_test_case(h2_sm_mock_goaway) +add_net_test_case(h2_sm_mock_cancel_after_goaway_no_double_complete) add_net_test_case(h2_sm_connection_ping) add_net_test_case(h2_sm_with_flow_control_err) add_net_test_case(h2_sm_with_initial_settings) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-http-0.10.14/tests/test_hpack.c new/aws-c-http-0.11.0/tests/test_hpack.c --- old/aws-c-http-0.10.14/tests/test_hpack.c 2026-03-31 22:04:47.000000000 +0200 +++ new/aws-c-http-0.11.0/tests/test_hpack.c 2026-05-21 22:22:41.000000000 +0200 @@ -815,6 +815,34 @@ return AWS_OP_SUCCESS; } +AWS_TEST_CASE(hpack_dynamic_table_growth_corner_case, test_hpack_dynamic_table_growth_corner_case) +static int test_hpack_dynamic_table_growth_corner_case(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + + aws_http_library_init(allocator); + struct aws_hpack_context context; + aws_hpack_context_init(&context, allocator, AWS_LS_HTTP_GENERAL, NULL); + + DEFINE_STATIC_HEADER(h1, "herp", "derp"); + DEFINE_STATIC_HEADER(h2, "fizz", "buzz"); + + const size_t h1_size = aws_hpack_get_header_size(&h1); + const size_t h2_size = aws_hpack_get_header_size(&h2); + + ASSERT_SUCCESS(aws_hpack_insert_header(&context, &h1)); + ASSERT_UINT_EQUALS(1, aws_hpack_get_dynamic_table_num_elements(&context)); + + ASSERT_SUCCESS(aws_hpack_resize_dynamic_table(&context, h1_size + h2_size + 1)); + ASSERT_UINT_EQUALS(1, aws_hpack_get_dynamic_table_num_elements(&context)); + + ASSERT_SUCCESS(aws_hpack_insert_header(&context, &h2)); + ASSERT_UINT_EQUALS(2, aws_hpack_get_dynamic_table_num_elements(&context)); + + aws_hpack_context_clean_up(&context); + aws_http_library_clean_up(); + return AWS_OP_SUCCESS; +} + AWS_TEST_CASE(hpack_dynamic_table_size_update_from_setting, test_hpack_dynamic_table_size_update_from_setting) static int test_hpack_dynamic_table_size_update_from_setting(struct aws_allocator *allocator, void *ctx) { (void)ctx; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-http-0.10.14/tests/test_stream_manager.c new/aws-c-http-0.11.0/tests/test_stream_manager.c --- old/aws-c-http-0.10.14/tests/test_stream_manager.c 2026-03-31 22:04:47.000000000 +0200 +++ new/aws-c-http-0.11.0/tests/test_stream_manager.c 2026-05-21 22:22:41.000000000 +0200 @@ -1152,6 +1152,63 @@ return s_tester_clean_up(); } +/* Test that cancelling a stream after GOAWAY does not crash from double stream completion. + * Reproduces P428540711: cancel() schedules cross-thread task, but s_finish_shutdown already + * completed the stream. The cross-thread task then invokes on_complete a second time. */ +TEST_CASE(h2_sm_mock_cancel_after_goaway_no_double_complete) { + (void)ctx; + struct sm_tester_options options = { + .max_connections = 1, + .max_concurrent_streams_per_connection = 1, + .alloc = allocator, + }; + ASSERT_SUCCESS(s_tester_init(&options)); + s_override_cm_connect_function(s_aws_http_connection_manager_create_connection_sync_mock); + + /* Acquire 1 stream */ + ASSERT_SUCCESS(s_sm_stream_acquiring(1)); + ASSERT_SUCCESS(s_wait_on_fake_connection_count(1)); + s_drain_all_fake_connection_testing_channel(); + ASSERT_SUCCESS(s_wait_on_streams_acquired_count(1)); + ASSERT_INT_EQUALS(0, s_tester.acquiring_stream_errors); + + struct sm_fake_connection *fake_connection = s_get_fake_connection(0); + ASSERT_SUCCESS(h2_fake_peer_send_connection_preface_default_settings(&fake_connection->peer)); + testing_channel_drain_queued_tasks(&fake_connection->testing_channel); + + /* Get the stream handle */ + struct aws_http_stream *stream = NULL; + aws_array_list_front(&s_tester.streams, &stream); + ASSERT_NOT_NULL(stream); + + /* Send GOAWAY with last_stream_id=0, meaning our stream (id=1) is rejected */ + struct aws_byte_cursor debug_info; + AWS_ZERO_STRUCT(debug_info); + struct aws_h2_frame *goaway_frame = + aws_h2_frame_new_goaway(allocator, 0 /*last_stream_id*/, AWS_HTTP2_ERR_INTERNAL_ERROR, debug_info); + ASSERT_SUCCESS(h2_fake_peer_send_frame(&fake_connection->peer, goaway_frame)); + + /* Cancel the stream BEFORE draining tasks. + * This schedules the cross-thread work task (reset_called=true). + * When we drain, both the GOAWAY processing (which completes the stream) + * and the cancel cross-thread task will run, causing double on_complete. */ + aws_http_stream_cancel_default_error(stream); + + /* User releases their ref on the stream (simulates real usage: cancel then release). + * The stream must stay alive until the cross-thread task completes. */ + aws_http_stream_release(stream); + aws_array_list_clear(&s_tester.streams); + + /* Drain tasks - this should NOT crash from double stream completion or use-after-free */ + testing_channel_drain_queued_tasks(&fake_connection->testing_channel); + + /* Stream should be completed with error at least once */ + ASSERT_TRUE(s_tester.stream_completed_count >= 1); + ASSERT_TRUE(s_tester.stream_complete_errors >= 1); + + return s_tester_clean_up(); +} + /* Test that PING works as expected. */ TEST_CASE(h2_sm_connection_ping) { (void)ctx;
