From 04ec3ca6ae564f8ce0769cfd24ef4729a3781b7a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 25 Aug 2025 10:12:27 +0000 Subject: [PATCH 1/2] Initial plan From a22e936c675c9a15f9c3ad8a6f4a519a94935bac Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 25 Aug 2025 10:22:44 +0000 Subject: [PATCH 2/2] Fix AMQP09 panic when exchangeDeclareArgs is nil - issue #3576 Co-authored-by: mmatczuk <1617930+mmatczuk@users.noreply.github.com> --- internal/impl/amqp09/output.go | 7 ++- internal/impl/amqp09/output_test.go | 80 +++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 internal/impl/amqp09/output_test.go diff --git a/internal/impl/amqp09/output.go b/internal/impl/amqp09/output.go index b7cd492448..b7c3bd8601 100644 --- a/internal/impl/amqp09/output.go +++ b/internal/impl/amqp09/output.go @@ -251,8 +251,11 @@ func amqp09WriterFromParsed(conf *service.ParsedConfig, mgr *service.Resources) if err != nil { return nil, err } - for key, value := range args { - a.exchangeDeclareArgs[key] = value + if len(args) > 0 { + a.exchangeDeclareArgs = make(amqp.Table) + for key, value := range args { + a.exchangeDeclareArgs[key] = value + } } } } diff --git a/internal/impl/amqp09/output_test.go b/internal/impl/amqp09/output_test.go new file mode 100644 index 0000000000..7bcfa8a939 --- /dev/null +++ b/internal/impl/amqp09/output_test.go @@ -0,0 +1,80 @@ +// Copyright 2024 Redpanda Data, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package amqp09 + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/redpanda-data/benthos/v4/public/service" +) + +func TestAMQP09WriterFromParsedWithExchangeDeclareArgs(t *testing.T) { + // This test reproduces issue #3576 - panic when exchangeDeclareArgs is nil + // but we try to assign to it when exchange_declare.arguments is configured + + configYAML := ` +urls: + - amqp://guest:guest@localhost:5672/ +exchange: test-exchange +exchange_declare: + enabled: true + type: direct + durable: true + arguments: + alternate-exchange: my-ae + x-message-ttl: 60000 +` + + spec := amqp09OutputSpec() + config, err := spec.ParseYAML(configYAML, nil) + require.NoError(t, err) + + // This should not panic + writer, err := amqp09WriterFromParsed(config, service.MockResources()) + require.NoError(t, err) + require.NotNil(t, writer) + + // Verify that the arguments were properly set + require.NotNil(t, writer.exchangeDeclareArgs) + require.Equal(t, "my-ae", writer.exchangeDeclareArgs["alternate-exchange"]) + require.Equal(t, "60000", writer.exchangeDeclareArgs["x-message-ttl"]) +} + +func TestAMQP09WriterFromParsedWithoutExchangeDeclareArgs(t *testing.T) { + // Test that configuration without arguments still works + + configYAML := ` +urls: + - amqp://guest:guest@localhost:5672/ +exchange: test-exchange +exchange_declare: + enabled: true + type: direct + durable: true +` + + spec := amqp09OutputSpec() + config, err := spec.ParseYAML(configYAML, nil) + require.NoError(t, err) + + writer, err := amqp09WriterFromParsed(config, service.MockResources()) + require.NoError(t, err) + require.NotNil(t, writer) + + // exchangeDeclareArgs should remain nil when no arguments are configured + require.Nil(t, writer.exchangeDeclareArgs) +} \ No newline at end of file