aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2022-03-18 12:14:20 -0700
committerHeschi Kreinick <heschi@google.com>2022-03-30 16:42:29 +0000
commit8b0583a05441b84a99d03daa78a24306c85cddd3 (patch)
treecf9a056c55ecddd4af6a7fbf752a98d2f0ae55ae
parent677c6fe94c69b4fa35503e4afd36e8ef0e1394c5 (diff)
downloadgo-8b0583a05441b84a99d03daa78a24306c85cddd3.tar.gz
go-8b0583a05441b84a99d03daa78a24306c85cddd3.zip
[release-branch.go1.18] bytes: restore old Trim/TrimLeft behavior for nil
Keep returning nil for the cases where we historically returned nil, even though this is slightly different for TrimLeft and TrimRight. For #51793 Fixes #51796 Change-Id: Ifbdfc6b09d52b8e063cfe6341019f9b2eb8b70e9 Reviewed-on: https://go-review.googlesource.com/c/go/+/393876 Trust: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> (cherry picked from commit 32fdad19a246143ae4f194d1b39886d778de1380) Reviewed-on: https://go-review.googlesource.com/c/go/+/396294 Reviewed-by: Austin Clements <austin@google.com>
-rw-r--r--src/bytes/bytes.go24
-rw-r--r--src/bytes/bytes_test.go93
2 files changed, 106 insertions, 11 deletions
diff --git a/src/bytes/bytes.go b/src/bytes/bytes.go
index 41323ad549..e3dab4d035 100644
--- a/src/bytes/bytes.go
+++ b/src/bytes/bytes.go
@@ -909,7 +909,11 @@ func containsRune(s string, r rune) bool {
// Trim returns a subslice of s by slicing off all leading and
// trailing UTF-8-encoded code points contained in cutset.
func Trim(s []byte, cutset string) []byte {
- if len(s) == 0 || cutset == "" {
+ if len(s) == 0 {
+ // This is what we've historically done.
+ return nil
+ }
+ if cutset == "" {
return s
}
if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
@@ -924,7 +928,11 @@ func Trim(s []byte, cutset string) []byte {
// TrimLeft returns a subslice of s by slicing off all leading
// UTF-8-encoded code points contained in cutset.
func TrimLeft(s []byte, cutset string) []byte {
- if len(s) == 0 || cutset == "" {
+ if len(s) == 0 {
+ // This is what we've historically done.
+ return nil
+ }
+ if cutset == "" {
return s
}
if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
@@ -940,6 +948,10 @@ func trimLeftByte(s []byte, c byte) []byte {
for len(s) > 0 && s[0] == c {
s = s[1:]
}
+ if len(s) == 0 {
+ // This is what we've historically done.
+ return nil
+ }
return s
}
@@ -950,6 +962,10 @@ func trimLeftASCII(s []byte, as *asciiSet) []byte {
}
s = s[1:]
}
+ if len(s) == 0 {
+ // This is what we've historically done.
+ return nil
+ }
return s
}
@@ -964,6 +980,10 @@ func trimLeftUnicode(s []byte, cutset string) []byte {
}
s = s[n:]
}
+ if len(s) == 0 {
+ // This is what we've historically done.
+ return nil
+ }
return s
}
diff --git a/src/bytes/bytes_test.go b/src/bytes/bytes_test.go
index 3bece6adf0..2e6ab31540 100644
--- a/src/bytes/bytes_test.go
+++ b/src/bytes/bytes_test.go
@@ -1278,24 +1278,69 @@ var trimTests = []TrimTest{
{"TrimSuffix", "aabb", "b", "aab"},
}
+type TrimNilTest struct {
+ f string
+ in []byte
+ arg string
+ out []byte
+}
+
+var trimNilTests = []TrimNilTest{
+ {"Trim", nil, "", nil},
+ {"Trim", []byte{}, "", nil},
+ {"Trim", []byte{'a'}, "a", nil},
+ {"Trim", []byte{'a', 'a'}, "a", nil},
+ {"Trim", []byte{'a'}, "ab", nil},
+ {"Trim", []byte{'a', 'b'}, "ab", nil},
+ {"Trim", []byte("☺"), "☺", nil},
+ {"TrimLeft", nil, "", nil},
+ {"TrimLeft", []byte{}, "", nil},
+ {"TrimLeft", []byte{'a'}, "a", nil},
+ {"TrimLeft", []byte{'a', 'a'}, "a", nil},
+ {"TrimLeft", []byte{'a'}, "ab", nil},
+ {"TrimLeft", []byte{'a', 'b'}, "ab", nil},
+ {"TrimLeft", []byte("☺"), "☺", nil},
+ {"TrimRight", nil, "", nil},
+ {"TrimRight", []byte{}, "", []byte{}},
+ {"TrimRight", []byte{'a'}, "a", []byte{}},
+ {"TrimRight", []byte{'a', 'a'}, "a", []byte{}},
+ {"TrimRight", []byte{'a'}, "ab", []byte{}},
+ {"TrimRight", []byte{'a', 'b'}, "ab", []byte{}},
+ {"TrimRight", []byte("☺"), "☺", []byte{}},
+ {"TrimPrefix", nil, "", nil},
+ {"TrimPrefix", []byte{}, "", []byte{}},
+ {"TrimPrefix", []byte{'a'}, "a", []byte{}},
+ {"TrimPrefix", []byte("☺"), "☺", []byte{}},
+ {"TrimSuffix", nil, "", nil},
+ {"TrimSuffix", []byte{}, "", []byte{}},
+ {"TrimSuffix", []byte{'a'}, "a", []byte{}},
+ {"TrimSuffix", []byte("☺"), "☺", []byte{}},
+}
+
func TestTrim(t *testing.T) {
- for _, tc := range trimTests {
- name := tc.f
- var f func([]byte, string) []byte
- var fb func([]byte, []byte) []byte
+ toFn := func(name string) (func([]byte, string) []byte, func([]byte, []byte) []byte) {
switch name {
case "Trim":
- f = Trim
+ return Trim, nil
case "TrimLeft":
- f = TrimLeft
+ return TrimLeft, nil
case "TrimRight":
- f = TrimRight
+ return TrimRight, nil
case "TrimPrefix":
- fb = TrimPrefix
+ return nil, TrimPrefix
case "TrimSuffix":
- fb = TrimSuffix
+ return nil, TrimSuffix
default:
t.Errorf("Undefined trim function %s", name)
+ return nil, nil
+ }
+ }
+
+ for _, tc := range trimTests {
+ name := tc.f
+ f, fb := toFn(name)
+ if f == nil && fb == nil {
+ continue
}
var actual string
if f != nil {
@@ -1307,6 +1352,36 @@ func TestTrim(t *testing.T) {
t.Errorf("%s(%q, %q) = %q; want %q", name, tc.in, tc.arg, actual, tc.out)
}
}
+
+ for _, tc := range trimNilTests {
+ name := tc.f
+ f, fb := toFn(name)
+ if f == nil && fb == nil {
+ continue
+ }
+ var actual []byte
+ if f != nil {
+ actual = f(tc.in, tc.arg)
+ } else {
+ actual = fb(tc.in, []byte(tc.arg))
+ }
+ report := func(s []byte) string {
+ if s == nil {
+ return "nil"
+ } else {
+ return fmt.Sprintf("%q", s)
+ }
+ }
+ if len(actual) != 0 {
+ t.Errorf("%s(%s, %q) returned non-empty value", name, report(tc.in), tc.arg)
+ } else {
+ actualNil := actual == nil
+ outNil := tc.out == nil
+ if actualNil != outNil {
+ t.Errorf("%s(%s, %q) got nil %t; want nil %t", name, report(tc.in), tc.arg, actualNil, outNil)
+ }
+ }
+ }
}
type predicate struct {