Skip to content

Commit 77c8957

Browse files
authored
Fix isAllowed of escapeStreamer (#22814) (#22837)
Backport #22814. The use of `sort.Search` is wrong: The slice should be sorted, and `return >= 0` doen't mean it exists, see the [manual](https://pkg.go.dev/sort#Search). Could be fixed like this if we really need it: ```diff diff --git a/modules/charset/escape_stream.go b/modules/charset/escape_stream.go index 823b635..fcf1ffb 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 } ``` But I don't think so, a map is better to do it.
1 parent 68b908d commit 77c8957

File tree

1 file changed

+7
-17
lines changed

1 file changed

+7
-17
lines changed

modules/charset/escape_stream.go

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ package charset
77
import (
88
"fmt"
99
"regexp"
10-
"sort"
1110
"strings"
1211
"unicode"
1312
"unicode/utf8"
@@ -21,12 +20,16 @@ import (
2120
var defaultWordRegexp = regexp.MustCompile(`(-?\d*\.\d\w*)|([^\` + "`" + `\~\!\@\#\$\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s\x00-\x1f]+)`)
2221

2322
func NewEscapeStreamer(locale translation.Locale, next HTMLStreamer, allowed ...rune) HTMLStreamer {
23+
allowedM := make(map[rune]bool, len(allowed))
24+
for _, v := range allowed {
25+
allowedM[v] = true
26+
}
2427
return &escapeStreamer{
2528
escaped: &EscapeStatus{},
2629
PassthroughHTMLStreamer: *NewPassthroughStreamer(next),
2730
locale: locale,
2831
ambiguousTables: AmbiguousTablesForLocale(locale),
29-
allowed: allowed,
32+
allowed: allowedM,
3033
}
3134
}
3235

@@ -35,7 +38,7 @@ type escapeStreamer struct {
3538
escaped *EscapeStatus
3639
locale translation.Locale
3740
ambiguousTables []*AmbiguousTable
38-
allowed []rune
41+
allowed map[rune]bool
3942
}
4043

4144
func (e *escapeStreamer) EscapeStatus() *EscapeStatus {
@@ -257,7 +260,7 @@ func (e *escapeStreamer) runeTypes(runes ...rune) (types []runeType, confusables
257260
runeCounts.numBrokenRunes++
258261
case r == ' ' || r == '\t' || r == '\n':
259262
runeCounts.numBasicRunes++
260-
case e.isAllowed(r):
263+
case e.allowed[r]:
261264
if r > 0x7e || r < 0x20 {
262265
types[i] = nonBasicASCIIRuneType
263266
runeCounts.numNonConfusingNonBasicRunes++
@@ -283,16 +286,3 @@ func (e *escapeStreamer) runeTypes(runes ...rune) (types []runeType, confusables
283286
}
284287
return types, confusables, runeCounts
285288
}
286-
287-
func (e *escapeStreamer) isAllowed(r rune) bool {
288-
if len(e.allowed) == 0 {
289-
return false
290-
}
291-
if len(e.allowed) == 1 {
292-
return e.allowed[0] == r
293-
}
294-
295-
return sort.Search(len(e.allowed), func(i int) bool {
296-
return e.allowed[i] >= r
297-
}) >= 0
298-
}

0 commit comments

Comments
 (0)