From bcc4be9f8be792332494453042fe3357e93262d9 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Tue, 1 Sep 2026 21:10:29 +0200 Subject: [PATCH] cmd/docker: fix stringSliceReplaceAt with overlapping matches Inline the sub-slice lookup into stringSliceReplaceAt and use slices.Equal to compare candidate ranges. When a specific index is required, check that position directly instead of searching the full slice. This also fixes overlapping matches and uses slices.Concat to construct the replacement result. Signed-off-by: Sebastiaan van Stijn --- cmd/docker/aliases_utils.go | 44 ++++++++++++++------------------ cmd/docker/aliases_utils_test.go | 9 +++++++ 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/cmd/docker/aliases_utils.go b/cmd/docker/aliases_utils.go index b14fee0a92..fbf1c7e98e 100644 --- a/cmd/docker/aliases_utils.go +++ b/cmd/docker/aliases_utils.go @@ -1,32 +1,26 @@ package main -func stringSliceIndex(s, subs []string) int { - j := 0 - if len(subs) > 0 { - for i, x := range s { - if j < len(subs) && subs[j] == x { - j++ - } else { - j = 0 - } - if len(subs) == j { - return i + 1 - j - } - } - } - return -1 -} +import "slices" -// stringSliceReplaceAt replaces the sub-slice find, with the sub-slice replace, in the string -// slice s, returning a new slice and a boolean indicating if the replacement happened. -// requireIdx is the index at which old needs to be found at (or -1 to disregard that). +// stringSliceReplaceAt replaces the sub-slice find with the sub-slice replace in s, +// returning a new slice and a boolean indicating whether the replacement happened. +// requireIndex is the index at which find must be found, or -1 to disregard it. func stringSliceReplaceAt(s, find, replace []string, requireIndex int) ([]string, bool) { - idx := stringSliceIndex(s, find) - if (requireIndex != -1 && requireIndex != idx) || idx == -1 { + if len(find) == 0 { return s, false } - out := append([]string{}, s[:idx]...) - out = append(out, replace...) - out = append(out, s[idx+len(find):]...) - return out, true + + if requireIndex >= 0 { + if requireIndex+len(find) > len(s) || !slices.Equal(s[requireIndex:requireIndex+len(find)], find) { + return s, false + } + return slices.Concat(s[:requireIndex], replace, s[requireIndex+len(find):]), true + } + + for i := range len(s) - len(find) + 1 { + if slices.Equal(s[i:i+len(find)], find) { + return slices.Concat(s[:i], replace, s[i+len(find):]), true + } + } + return s, false } diff --git a/cmd/docker/aliases_utils_test.go b/cmd/docker/aliases_utils_test.go index 3afc964783..38db6caf94 100644 --- a/cmd/docker/aliases_utils_test.go +++ b/cmd/docker/aliases_utils_test.go @@ -65,6 +65,15 @@ func TestStringSliceReplaceAt(t *testing.T) { requireIndex: -1, expected: []string{"foo"}, }, + { + name: "overlapping match", + s: []string{"a", "a", "b"}, + find: []string{"a", "b"}, + replace: []string{"c"}, + requireIndex: -1, + expected: []string{"a", "c"}, + ok: true, + }, } for _, tc := range tests {