slices: don't accept out of order indexes in Replace
Panic instead, as documented.
Fixes golang/go#56700
Change-Id: I47000f6f190278a54056cd229cb5a9bb5a6c1a90
Reviewed-on: https://go-review.googlesource.com/c/exp/+/449915
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
diff --git a/slices/slices.go b/slices/slices.go
index ff8b5d8..6b7928e 100644
--- a/slices/slices.go
+++ b/slices/slices.go
@@ -165,6 +165,7 @@
// Replace replaces the elements s[i:j] by the given v, and returns the
// modified slice. Replace panics if s[i:j] is not a valid slice of s.
func Replace[S ~[]E, E any](s S, i, j int, v ...E) S {
+ _ = s[i:j] // verify that i:j is a valid subslice
tot := len(s[:i]) + len(v) + len(s[j:])
if tot <= cap(s) {
s2 := s[:tot]
diff --git a/slices/slices_test.go b/slices/slices_test.go
index 35ccad5..7473886 100644
--- a/slices/slices_test.go
+++ b/slices/slices_test.go
@@ -683,6 +683,23 @@
}
}
+func TestReplacePanics(t *testing.T) {
+ for _, test := range []struct {
+ name string
+ s, v []int
+ i, j int
+ }{
+ {"indexes out of order", []int{1, 2}, []int{3}, 2, 1},
+ {"large index", []int{1, 2}, []int{3}, 1, 10},
+ {"negative index", []int{1, 2}, []int{3}, -1, 2},
+ } {
+ ss, vv := Clone(test.s), Clone(test.v)
+ if !panics(func() { Replace(ss, test.i, test.j, vv...) }) {
+ t.Errorf("Replace %s: should have panicked", test.name)
+ }
+ }
+}
+
func BenchmarkReplace(b *testing.B) {
cases := []struct {
name string