From a7f58e6f181121cac5bc5dfb58a0f72d738cd5aa Mon Sep 17 00:00:00 2001 From: wanglimin Date: Wed, 21 Dec 2022 14:46:41 +0800 Subject: [PATCH] support Cut in bytes,strings --- ...o1.18-add-definition-byte-string-cut.patch | 434 ++++++++++++++++++ golang.spec | 6 +- 2 files changed, 439 insertions(+), 1 deletion(-) create mode 100644 0024-release-branch.go1.18-add-definition-byte-string-cut.patch diff --git a/0024-release-branch.go1.18-add-definition-byte-string-cut.patch b/0024-release-branch.go1.18-add-definition-byte-string-cut.patch new file mode 100644 index 0000000..61de000 --- /dev/null +++ b/0024-release-branch.go1.18-add-definition-byte-string-cut.patch @@ -0,0 +1,434 @@ +From 719a248de7215aeb2ca38e71c0056a777712f1e2 Mon Sep 17 00:00:00 2001 +From: Russ Cox +Date: Tue, 21 Sep 2021 10:59:16 -0400 +Subject: [PATCH] bytes, strings: add Cut + +Using Cut is a clearer way to write the vast majority (>70%) +of existing code that calls Index, IndexByte, IndexRune, and SplitN. +There is more discussion on https://golang.org/issue/46336. + +Fixes #46336. + +Change-Id: Ia418ed7c3706c65bf61e1b2c5baf534cb783e4d3 +Reviewed-on: https://go-review.googlesource.com/c/go/+/351710 +Trust: Russ Cox +Run-TryBot: Russ Cox +TryBot-Result: Go Bot +Reviewed-by: Ian Lance Taylor +--- + src/bytes/bytes.go | 13 ++++ + src/bytes/bytes_test.go | 23 ++++++ + src/bytes/example_test.go | 138 ++++++++++++++++++------------------ + src/strings/example_test.go | 58 +++++++++------ + src/strings/strings.go | 11 +++ + src/strings/strings_test.go | 25 ++++++- + 6 files changed, 178 insertions(+), 90 deletions(-) + +diff --git a/src/bytes/bytes.go b/src/bytes/bytes.go +index ce52649f13..ec9a2eb693 100644 +--- a/src/bytes/bytes.go ++++ b/src/bytes/bytes.go +@@ -1174,3 +1174,16 @@ func Index(s, sep []byte) int { + } + return -1 + } ++ ++// Cut slices s around the first instance of sep, ++// returning the text before and after sep. ++// The found result reports whether sep appears in s. ++// If sep does not appear in s, cut returns s, "", false. ++// ++// Cut returns slices of the original slice s, not copies. ++func Cut(s, sep []byte) (before, after []byte, found bool) { ++ if i := Index(s, sep); i >= 0 { ++ return s[:i], s[i+len(sep):], true ++ } ++ return s, nil, false ++} +diff --git a/src/bytes/bytes_test.go b/src/bytes/bytes_test.go +index 544ee46f90..538e613c8e 100644 +--- a/src/bytes/bytes_test.go ++++ b/src/bytes/bytes_test.go +@@ -1565,6 +1565,29 @@ func TestEqualFold(t *testing.T) { + } + } + ++var cutTests = []struct { ++ s, sep string ++ before, after string ++ found bool ++}{ ++ {"abc", "b", "a", "c", true}, ++ {"abc", "a", "", "bc", true}, ++ {"abc", "c", "ab", "", true}, ++ {"abc", "abc", "", "", true}, ++ {"abc", "", "", "abc", true}, ++ {"abc", "d", "abc", "", false}, ++ {"", "d", "", "", false}, ++ {"", "", "", "", true}, ++} ++ ++func TestCut(t *testing.T) { ++ for _, tt := range cutTests { ++ if before, after, found := Cut([]byte(tt.s), []byte(tt.sep)); string(before) != tt.before || string(after) != tt.after || found != tt.found { ++ t.Errorf("Cut(%q, %q) = %q, %q, %v, want %q, %q, %v", tt.s, tt.sep, before, after, found, tt.before, tt.after, tt.found) ++ } ++ } ++} ++ + func TestBufferGrowNegative(t *testing.T) { + defer func() { + if err := recover(); err == nil { +diff --git a/src/bytes/example_test.go b/src/bytes/example_test.go +index ae93202b57..a1a6c2d292 100644 +--- a/src/bytes/example_test.go ++++ b/src/bytes/example_test.go +@@ -92,36 +92,6 @@ func ExampleCompare_search() { + } + } + +-func ExampleTrimSuffix() { +- var b = []byte("Hello, goodbye, etc!") +- b = bytes.TrimSuffix(b, []byte("goodbye, etc!")) +- b = bytes.TrimSuffix(b, []byte("gopher")) +- b = append(b, bytes.TrimSuffix([]byte("world!"), []byte("x!"))...) +- os.Stdout.Write(b) +- // Output: Hello, world! +-} +- +-func ExampleTrimPrefix() { +- var b = []byte("Goodbye,, world!") +- b = bytes.TrimPrefix(b, []byte("Goodbye,")) +- b = bytes.TrimPrefix(b, []byte("See ya,")) +- fmt.Printf("Hello%s", b) +- // Output: Hello, world! +-} +- +-func ExampleFields() { +- fmt.Printf("Fields are: %q", bytes.Fields([]byte(" foo bar baz "))) +- // Output: Fields are: ["foo" "bar" "baz"] +-} +- +-func ExampleFieldsFunc() { +- f := func(c rune) bool { +- return !unicode.IsLetter(c) && !unicode.IsNumber(c) +- } +- fmt.Printf("Fields are: %q", bytes.FieldsFunc([]byte(" foo1;bar2,baz3..."), f)) +- // Output: Fields are: ["foo1" "bar2" "baz3"] +-} +- + func ExampleContains() { + fmt.Println(bytes.Contains([]byte("seafood"), []byte("foo"))) + fmt.Println(bytes.Contains([]byte("seafood"), []byte("bar"))) +@@ -168,6 +138,22 @@ func ExampleCount() { + // 5 + } + ++func ExampleCut() { ++ show := func(s, sep string) { ++ before, after, found := bytes.Cut([]byte(s), []byte(sep)) ++ fmt.Printf("Cut(%q, %q) = %q, %q, %v\n", s, sep, before, after, found) ++ } ++ show("Gopher", "Go") ++ show("Gopher", "ph") ++ show("Gopher", "er") ++ show("Gopher", "Badger") ++ // Output: ++ // Cut("Gopher", "Go") = "", "pher", true ++ // Cut("Gopher", "ph") = "Go", "er", true ++ // Cut("Gopher", "er") = "Goph", "", true ++ // Cut("Gopher", "Badger") = "Gopher", "", false ++} ++ + func ExampleEqual() { + fmt.Println(bytes.Equal([]byte("Go"), []byte("Go"))) + fmt.Println(bytes.Equal([]byte("Go"), []byte("C++"))) +@@ -181,6 +167,19 @@ func ExampleEqualFold() { + // Output: true + } + ++func ExampleFields() { ++ fmt.Printf("Fields are: %q", bytes.Fields([]byte(" foo bar baz "))) ++ // Output: Fields are: ["foo" "bar" "baz"] ++} ++ ++func ExampleFieldsFunc() { ++ f := func(c rune) bool { ++ return !unicode.IsLetter(c) && !unicode.IsNumber(c) ++ } ++ fmt.Printf("Fields are: %q", bytes.FieldsFunc([]byte(" foo1;bar2,baz3..."), f)) ++ // Output: Fields are: ["foo1" "bar2" "baz3"] ++} ++ + func ExampleHasPrefix() { + fmt.Println(bytes.HasPrefix([]byte("Gopher"), []byte("Go"))) + fmt.Println(bytes.HasPrefix([]byte("Gopher"), []byte("C"))) +@@ -246,6 +245,12 @@ func ExampleIndexRune() { + // -1 + } + ++func ExampleJoin() { ++ s := [][]byte{[]byte("foo"), []byte("bar"), []byte("baz")} ++ fmt.Printf("%s", bytes.Join(s, []byte(", "))) ++ // Output: foo, bar, baz ++} ++ + func ExampleLastIndex() { + fmt.Println(bytes.Index([]byte("go gopher"), []byte("go"))) + fmt.Println(bytes.LastIndex([]byte("go gopher"), []byte("go"))) +@@ -286,10 +291,12 @@ func ExampleLastIndexFunc() { + // -1 + } + +-func ExampleJoin() { +- s := [][]byte{[]byte("foo"), []byte("bar"), []byte("baz")} +- fmt.Printf("%s", bytes.Join(s, []byte(", "))) +- // Output: foo, bar, baz ++func ExampleReader_Len() { ++ fmt.Println(bytes.NewReader([]byte("Hi!")).Len()) ++ fmt.Println(bytes.NewReader([]byte("こんにちは!")).Len()) ++ // Output: ++ // 3 ++ // 16 + } + + func ExampleRepeat() { +@@ -399,20 +406,6 @@ func ExampleTrimFunc() { + // go-gopher! + } + +-func ExampleMap() { +- rot13 := func(r rune) rune { +- switch { +- case r >= 'A' && r <= 'Z': +- return 'A' + (r-'A'+13)%26 +- case r >= 'a' && r <= 'z': +- return 'a' + (r-'a'+13)%26 +- } +- return r +- } +- fmt.Printf("%s", bytes.Map(rot13, []byte("'Twas brillig and the slithy gopher..."))) +- // Output: 'Gjnf oevyyvt naq gur fyvgul tbcure... +-} +- + func ExampleTrimLeft() { + fmt.Print(string(bytes.TrimLeft([]byte("453gopher8257"), "0123456789"))) + // Output: +@@ -429,11 +422,28 @@ func ExampleTrimLeftFunc() { + // go-gopher!567 + } + ++func ExampleTrimPrefix() { ++ var b = []byte("Goodbye,, world!") ++ b = bytes.TrimPrefix(b, []byte("Goodbye,")) ++ b = bytes.TrimPrefix(b, []byte("See ya,")) ++ fmt.Printf("Hello%s", b) ++ // Output: Hello, world! ++} ++ + func ExampleTrimSpace() { + fmt.Printf("%s", bytes.TrimSpace([]byte(" \t\n a lone gopher \n\t\r\n"))) + // Output: a lone gopher + } + ++func ExampleTrimSuffix() { ++ var b = []byte("Hello, goodbye, etc!") ++ b = bytes.TrimSuffix(b, []byte("goodbye, etc!")) ++ b = bytes.TrimSuffix(b, []byte("gopher")) ++ b = append(b, bytes.TrimSuffix([]byte("world!"), []byte("x!"))...) ++ os.Stdout.Write(b) ++ // Output: Hello, world! ++} ++ + func ExampleTrimRight() { + fmt.Print(string(bytes.TrimRight([]byte("453gopher8257"), "0123456789"))) + // Output: +@@ -450,21 +460,6 @@ func ExampleTrimRightFunc() { + // 1234go-gopher! + } + +-func ExampleToUpper() { +- fmt.Printf("%s", bytes.ToUpper([]byte("Gopher"))) +- // Output: GOPHER +-} +- +-func ExampleToUpperSpecial() { +- str := []byte("ahoj vývojári golang") +- totitle := bytes.ToUpperSpecial(unicode.AzeriCase, str) +- fmt.Println("Original : " + string(str)) +- fmt.Println("ToUpper : " + string(totitle)) +- // Output: +- // Original : ahoj vývojári golang +- // ToUpper : AHOJ VÝVOJÁRİ GOLANG +-} +- + func ExampleToLower() { + fmt.Printf("%s", bytes.ToLower([]byte("Gopher"))) + // Output: gopher +@@ -480,10 +475,17 @@ func ExampleToLowerSpecial() { + // ToLower : ahoj vývojári golang + } + +-func ExampleReader_Len() { +- fmt.Println(bytes.NewReader([]byte("Hi!")).Len()) +- fmt.Println(bytes.NewReader([]byte("こんにちは!")).Len()) ++func ExampleToUpper() { ++ fmt.Printf("%s", bytes.ToUpper([]byte("Gopher"))) ++ // Output: GOPHER ++} ++ ++func ExampleToUpperSpecial() { ++ str := []byte("ahoj vývojári golang") ++ totitle := bytes.ToUpperSpecial(unicode.AzeriCase, str) ++ fmt.Println("Original : " + string(str)) ++ fmt.Println("ToUpper : " + string(totitle)) + // Output: +- // 3 +- // 16 ++ // Original : ahoj vývojári golang ++ // ToUpper : AHOJ VÝVOJÁRİ GOLANG + } +diff --git a/src/strings/example_test.go b/src/strings/example_test.go +index 375f9cac65..94aa167f90 100644 +--- a/src/strings/example_test.go ++++ b/src/strings/example_test.go +@@ -10,17 +10,15 @@ import ( + "unicode" + ) + +-func ExampleFields() { +- fmt.Printf("Fields are: %q", strings.Fields(" foo bar baz ")) +- // Output: Fields are: ["foo" "bar" "baz"] +-} +- +-func ExampleFieldsFunc() { +- f := func(c rune) bool { +- return !unicode.IsLetter(c) && !unicode.IsNumber(c) ++func ExampleBuilder() { ++ var b strings.Builder ++ for i := 3; i >= 1; i-- { ++ fmt.Fprintf(&b, "%d...", i) + } +- fmt.Printf("Fields are: %q", strings.FieldsFunc(" foo1;bar2,baz3...", f)) +- // Output: Fields are: ["foo1" "bar2" "baz3"] ++ b.WriteString("ignition") ++ fmt.Println(b.String()) ++ ++ // Output: 3...2...1...ignition + } + + func ExampleCompare() { +@@ -79,11 +77,40 @@ func ExampleCount() { + // 5 + } + ++func ExampleCut() { ++ show := func(s, sep string) { ++ before, after, found := strings.Cut(s, sep) ++ fmt.Printf("Cut(%q, %q) = %q, %q, %v\n", s, sep, before, after, found) ++ } ++ show("Gopher", "Go") ++ show("Gopher", "ph") ++ show("Gopher", "er") ++ show("Gopher", "Badger") ++ // Output: ++ // Cut("Gopher", "Go") = "", "pher", true ++ // Cut("Gopher", "ph") = "Go", "er", true ++ // Cut("Gopher", "er") = "Goph", "", true ++ // Cut("Gopher", "Badger") = "Gopher", "", false ++} ++ + func ExampleEqualFold() { + fmt.Println(strings.EqualFold("Go", "go")) + // Output: true + } + ++func ExampleFields() { ++ fmt.Printf("Fields are: %q", strings.Fields(" foo bar baz ")) ++ // Output: Fields are: ["foo" "bar" "baz"] ++} ++ ++func ExampleFieldsFunc() { ++ f := func(c rune) bool { ++ return !unicode.IsLetter(c) && !unicode.IsNumber(c) ++ } ++ fmt.Printf("Fields are: %q", strings.FieldsFunc(" foo1;bar2,baz3...", f)) ++ // Output: Fields are: ["foo1" "bar2" "baz3"] ++} ++ + func ExampleHasPrefix() { + fmt.Println(strings.HasPrefix("Gopher", "Go")) + fmt.Println(strings.HasPrefix("Gopher", "C")) +@@ -370,14 +397,3 @@ func ExampleTrimRightFunc() { + })) + // Output: ¡¡¡Hello, Gophers + } +- +-func ExampleBuilder() { +- var b strings.Builder +- for i := 3; i >= 1; i-- { +- fmt.Fprintf(&b, "%d...", i) +- } +- b.WriteString("ignition") +- fmt.Println(b.String()) +- +- // Output: 3...2...1...ignition +-} +diff --git a/src/strings/strings.go b/src/strings/strings.go +index b429735fea..0c94395311 100644 +--- a/src/strings/strings.go ++++ b/src/strings/strings.go +@@ -1100,3 +1100,14 @@ func Index(s, substr string) int { + } + return -1 + } ++ ++// Cut slices s around the first instance of sep, ++// returning the text before and after sep. ++// The found result reports whether sep appears in s. ++// If sep does not appear in s, cut returns s, "", false. ++func Cut(s, sep string) (before, after string, found bool) { ++ if i := Index(s, sep); i >= 0 { ++ return s[:i], s[i+len(sep):], true ++ } ++ return s, "", false ++} +diff --git a/src/strings/strings_test.go b/src/strings/strings_test.go +index 09e5b27cc3..5a02ba496f 100644 +--- a/src/strings/strings_test.go ++++ b/src/strings/strings_test.go +@@ -1577,7 +1577,30 @@ var CountTests = []struct { + func TestCount(t *testing.T) { + for _, tt := range CountTests { + if num := Count(tt.s, tt.sep); num != tt.num { +- t.Errorf("Count(\"%s\", \"%s\") = %d, want %d", tt.s, tt.sep, num, tt.num) ++ t.Errorf("Count(%q, %q) = %d, want %d", tt.s, tt.sep, num, tt.num) ++ } ++ } ++} ++ ++var cutTests = []struct { ++ s, sep string ++ before, after string ++ found bool ++}{ ++ {"abc", "b", "a", "c", true}, ++ {"abc", "a", "", "bc", true}, ++ {"abc", "c", "ab", "", true}, ++ {"abc", "abc", "", "", true}, ++ {"abc", "", "", "abc", true}, ++ {"abc", "d", "abc", "", false}, ++ {"", "d", "", "", false}, ++ {"", "", "", "", true}, ++} ++ ++func TestCut(t *testing.T) { ++ for _, tt := range cutTests { ++ if before, after, found := Cut(tt.s, tt.sep); before != tt.before || after != tt.after || found != tt.found { ++ t.Errorf("Cut(%q, %q) = %q, %q, %v, want %q, %q, %v", tt.s, tt.sep, before, after, found, tt.before, tt.after, tt.found) + } + } + } +-- +2.21.0 + diff --git a/golang.spec b/golang.spec index 62640cc..5de473a 100644 --- a/golang.spec +++ b/golang.spec @@ -63,7 +63,7 @@ Name: golang Version: 1.17.3 -Release: 12 +Release: 13 Summary: The Go Programming Language License: BSD and Public Domain URL: https://golang.org/ @@ -173,6 +173,7 @@ Patch6020: 0020-release-branch.go1.18-regexp-limit-size-of-parsed-re.patch Patch6021: 0021-release-branch.go1.18-net-http-httputil-avoid-query-.patch Patch6022: 0022-release-branch.go1.18-archive-tar-limit-size-of-head.patch Patch6023: 0023-syscall-os-exec-reject-environment-variables-contain.patch +Patch6024: 0024-release-branch.go1.18-add-definition-byte-string-cut.patch ExclusiveArch: %{golang_arches} @@ -411,6 +412,9 @@ fi %files devel -f go-tests.list -f go-misc.list -f go-src.list %changelog +* Sat Dec 17 2022 wanglimin - 1.17.3-13 +- Add string cut + * Fri Oct 11 2022 hanchao - 1.17.3-12 - Type:CVE - CVE:CVE-2022-41716 -- Gitee