From 68b7e908c87bba7712f08e17cca8f49928d153e2 Mon Sep 17 00:00:00 2001 From: Jason Song Date: Wed, 8 Feb 2023 15:07:27 +0800 Subject: [PATCH 1/5] test: Test_escapeStreamer_isAllowed --- modules/charset/escape_stream_test.go | 48 +++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 modules/charset/escape_stream_test.go diff --git a/modules/charset/escape_stream_test.go b/modules/charset/escape_stream_test.go new file mode 100644 index 000000000000..5b0aa2743514 --- /dev/null +++ b/modules/charset/escape_stream_test.go @@ -0,0 +1,48 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package charset + +import ( + "fmt" + "testing" + + "code.gitea.io/gitea/modules/translation" + + "github.com/stretchr/testify/assert" +) + +func Test_escapeStreamer_isAllowed(t *testing.T) { + tests := []struct { + allowed []rune + r rune + want bool + }{ + { + allowed: nil, + r: 'a', + want: false, + }, + { + allowed: []rune{'a', 'b', 'c'}, + r: 'x', + want: false, + }, + { + allowed: []rune{'a', 'b', 'c'}, + r: 'a', + want: true, + }, + { + allowed: []rune{'c', 'b', 'a'}, + r: 'a', + want: true, + }, + } + for _, tt := range tests { + t.Run(fmt.Sprintf("%v %v", tt.r, tt.allowed), func(t *testing.T) { + e := NewEscapeStreamer(translation.NewLocale("en"), nil, tt.allowed...).(*escapeStreamer) + assert.Equalf(t, tt.want, e.isAllowed(tt.r), "isAllowed(%v)", tt.r) + }) + } +} From 2763ee716aeccf4baa6e71ba0cd11fa568c6763b Mon Sep 17 00:00:00 2001 From: Jason Song Date: Wed, 8 Feb 2023 15:07:47 +0800 Subject: [PATCH 2/5] fix: sort search --- modules/charset/escape_stream.go | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/modules/charset/escape_stream.go b/modules/charset/escape_stream.go index 823b635137eb..fcf1ffbc1709 100644 --- a/modules/charset/escape_stream.go +++ b/modules/charset/escape_stream.go @@ -20,6 +20,9 @@ import ( var defaultWordRegexp = regexp.MustCompile(`(-?\d*\.\d\w*)|([^\` + "`" + `\~\!\@\#\$\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s\x00-\x1f]+)`) func NewEscapeStreamer(locale translation.Locale, next HTMLStreamer, allowed ...rune) HTMLStreamer { + sort.Slice(allowed, func(i, j int) bool { + return allowed[i] < allowed[j] + }) return &escapeStreamer{ escaped: &EscapeStatus{}, PassthroughHTMLStreamer: *NewPassthroughStreamer(next), @@ -284,14 +287,8 @@ func (e *escapeStreamer) runeTypes(runes ...rune) (types []runeType, confusables } func (e *escapeStreamer) isAllowed(r rune) bool { - if len(e.allowed) == 0 { - return false - } - if len(e.allowed) == 1 { - return e.allowed[0] == r - } - - return sort.Search(len(e.allowed), func(i int) bool { + i := sort.Search(len(e.allowed), func(i int) bool { return e.allowed[i] >= r - }) >= 0 + }) + return i < len(e.allowed) && e.allowed[i] == r } From a4ba68b08a0bc23755ad0699ecf9e179e6154054 Mon Sep 17 00:00:00 2001 From: Jason Song Date: Wed, 8 Feb 2023 15:12:20 +0800 Subject: [PATCH 3/5] feat: use map --- modules/charset/escape_stream.go | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/modules/charset/escape_stream.go b/modules/charset/escape_stream.go index fcf1ffbc1709..fc42140986bc 100644 --- a/modules/charset/escape_stream.go +++ b/modules/charset/escape_stream.go @@ -6,7 +6,6 @@ package charset import ( "fmt" "regexp" - "sort" "strings" "unicode" "unicode/utf8" @@ -20,15 +19,16 @@ import ( var defaultWordRegexp = regexp.MustCompile(`(-?\d*\.\d\w*)|([^\` + "`" + `\~\!\@\#\$\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s\x00-\x1f]+)`) func NewEscapeStreamer(locale translation.Locale, next HTMLStreamer, allowed ...rune) HTMLStreamer { - sort.Slice(allowed, func(i, j int) bool { - return allowed[i] < allowed[j] - }) + allowedM := make(map[rune]struct{}, len(allowed)) + for _, v := range allowed { + allowedM[v] = struct{}{} + } return &escapeStreamer{ escaped: &EscapeStatus{}, PassthroughHTMLStreamer: *NewPassthroughStreamer(next), locale: locale, ambiguousTables: AmbiguousTablesForLocale(locale), - allowed: allowed, + allowed: allowedM, } } @@ -37,7 +37,7 @@ type escapeStreamer struct { escaped *EscapeStatus locale translation.Locale ambiguousTables []*AmbiguousTable - allowed []rune + allowed map[rune]struct{} } func (e *escapeStreamer) EscapeStatus() *EscapeStatus { @@ -287,8 +287,6 @@ func (e *escapeStreamer) runeTypes(runes ...rune) (types []runeType, confusables } func (e *escapeStreamer) isAllowed(r rune) bool { - i := sort.Search(len(e.allowed), func(i int) bool { - return e.allowed[i] >= r - }) - return i < len(e.allowed) && e.allowed[i] == r + _, ok := e.allowed[r] + return ok } From 772ae733bfcc8acc7085136b1975664f49778ae3 Mon Sep 17 00:00:00 2001 From: Jason Song Date: Wed, 8 Feb 2023 15:13:15 +0800 Subject: [PATCH 4/5] fix: use map bool --- modules/charset/escape_stream.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/charset/escape_stream.go b/modules/charset/escape_stream.go index fc42140986bc..fd868324b1a7 100644 --- a/modules/charset/escape_stream.go +++ b/modules/charset/escape_stream.go @@ -19,9 +19,9 @@ import ( var defaultWordRegexp = regexp.MustCompile(`(-?\d*\.\d\w*)|([^\` + "`" + `\~\!\@\#\$\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s\x00-\x1f]+)`) func NewEscapeStreamer(locale translation.Locale, next HTMLStreamer, allowed ...rune) HTMLStreamer { - allowedM := make(map[rune]struct{}, len(allowed)) + allowedM := make(map[rune]bool, len(allowed)) for _, v := range allowed { - allowedM[v] = struct{}{} + allowedM[v] = true } return &escapeStreamer{ escaped: &EscapeStatus{}, @@ -37,7 +37,7 @@ type escapeStreamer struct { escaped *EscapeStatus locale translation.Locale ambiguousTables []*AmbiguousTable - allowed map[rune]struct{} + allowed map[rune]bool } func (e *escapeStreamer) EscapeStatus() *EscapeStatus { From 553304d01b0a42fdc2f39bf5ccc3dc0d5b95a111 Mon Sep 17 00:00:00 2001 From: Jason Song Date: Wed, 8 Feb 2023 15:14:30 +0800 Subject: [PATCH 5/5] fix: remove isAllowed --- modules/charset/escape_stream.go | 7 +--- modules/charset/escape_stream_test.go | 48 --------------------------- 2 files changed, 1 insertion(+), 54 deletions(-) delete mode 100644 modules/charset/escape_stream_test.go diff --git a/modules/charset/escape_stream.go b/modules/charset/escape_stream.go index fd868324b1a7..1b956bf4ab1a 100644 --- a/modules/charset/escape_stream.go +++ b/modules/charset/escape_stream.go @@ -259,7 +259,7 @@ func (e *escapeStreamer) runeTypes(runes ...rune) (types []runeType, confusables runeCounts.numBrokenRunes++ case r == ' ' || r == '\t' || r == '\n': runeCounts.numBasicRunes++ - case e.isAllowed(r): + case e.allowed[r]: if r > 0x7e || r < 0x20 { types[i] = nonBasicASCIIRuneType runeCounts.numNonConfusingNonBasicRunes++ @@ -285,8 +285,3 @@ func (e *escapeStreamer) runeTypes(runes ...rune) (types []runeType, confusables } return types, confusables, runeCounts } - -func (e *escapeStreamer) isAllowed(r rune) bool { - _, ok := e.allowed[r] - return ok -} diff --git a/modules/charset/escape_stream_test.go b/modules/charset/escape_stream_test.go deleted file mode 100644 index 5b0aa2743514..000000000000 --- a/modules/charset/escape_stream_test.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2023 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package charset - -import ( - "fmt" - "testing" - - "code.gitea.io/gitea/modules/translation" - - "github.com/stretchr/testify/assert" -) - -func Test_escapeStreamer_isAllowed(t *testing.T) { - tests := []struct { - allowed []rune - r rune - want bool - }{ - { - allowed: nil, - r: 'a', - want: false, - }, - { - allowed: []rune{'a', 'b', 'c'}, - r: 'x', - want: false, - }, - { - allowed: []rune{'a', 'b', 'c'}, - r: 'a', - want: true, - }, - { - allowed: []rune{'c', 'b', 'a'}, - r: 'a', - want: true, - }, - } - for _, tt := range tests { - t.Run(fmt.Sprintf("%v %v", tt.r, tt.allowed), func(t *testing.T) { - e := NewEscapeStreamer(translation.NewLocale("en"), nil, tt.allowed...).(*escapeStreamer) - assert.Equalf(t, tt.want, e.isAllowed(tt.r), "isAllowed(%v)", tt.r) - }) - } -}