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 <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2026-09-01 21:30:59 +02:00
parent f0f38d5cb9
commit bcc4be9f8b
2 changed files with 28 additions and 25 deletions
+19 -25
View File
@@ -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
}
+9
View File
@@ -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 {