mirror of
https://github.com/docker/cli.git
synced 2026-09-27 09:46:01 -04:00
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:
+19
-25
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user