From d3a52e214a4e03ab7d3cdd3d1c7d8bd102807704 Mon Sep 17 00:00:00 2001 From: AlinsRan Date: Wed, 22 Jul 2026 08:38:28 +0800 Subject: [PATCH] fix: trim whitespace in comma-separated annotation values GetStringsAnnotation split values on commas without trimming, so values like "127.0.0.1, 0.0.0.0" produced a leading-space element that broke IP validation and stalled sync. Trim each element and drop blanks. Sync from apache/apisix-ingress-controller#2815 (fixes #2723) --- internal/adc/translator/annotations/types.go | 8 +- .../adc/translator/annotations/types_test.go | 74 +++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 internal/adc/translator/annotations/types_test.go diff --git a/internal/adc/translator/annotations/types.go b/internal/adc/translator/annotations/types.go index 61ef517f..4117b3f2 100644 --- a/internal/adc/translator/annotations/types.go +++ b/internal/adc/translator/annotations/types.go @@ -131,7 +131,13 @@ func (e *extractor) GetStringsAnnotation(name string) []string { if value == "" { return nil } - return strings.Split(value, ",") + var result []string + for _, item := range strings.Split(value, ",") { + if item = strings.TrimSpace(item); item != "" { + result = append(result, item) + } + } + return result } func (e *extractor) GetBoolAnnotation(name string) bool { diff --git a/internal/adc/translator/annotations/types_test.go b/internal/adc/translator/annotations/types_test.go new file mode 100644 index 00000000..1f324d51 --- /dev/null +++ b/internal/adc/translator/annotations/types_test.go @@ -0,0 +1,74 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You 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 annotations + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetStringsAnnotation(t *testing.T) { + const key = "test-key" + testCases := []struct { + name string + annotations map[string]string + expected []string + }{ + { + name: "no spaces", + annotations: map[string]string{key: "127.0.0.1,0.0.0.0"}, + expected: []string{"127.0.0.1", "0.0.0.0"}, + }, + { + name: "spaces after comma", + annotations: map[string]string{key: "127.0.0.1, 0.0.0.0"}, + expected: []string{"127.0.0.1", "0.0.0.0"}, + }, + { + name: "tabs and surrounding spaces", + annotations: map[string]string{key: " 127.0.0.1 ,\t0.0.0.0\t"}, + expected: []string{"127.0.0.1", "0.0.0.0"}, + }, + { + name: "empty and blank elements", + annotations: map[string]string{key: "127.0.0.1,, ,0.0.0.0,"}, + expected: []string{"127.0.0.1", "0.0.0.0"}, + }, + { + name: "single value", + annotations: map[string]string{key: "127.0.0.1"}, + expected: []string{"127.0.0.1"}, + }, + { + name: "all blank elements", + annotations: map[string]string{key: " , ,\t"}, + expected: nil, + }, + { + name: "absent annotation", + annotations: map[string]string{}, + expected: nil, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + e := NewExtractor(tc.annotations) + assert.Equal(t, tc.expected, e.GetStringsAnnotation(key)) + }) + } +}