Check utf8.RuneError result

Signed-off-by: Oleg Zaytsev <mail@olegzaytsev.com>
This commit is contained in:
Oleg Zaytsev 2024-05-13 17:44:07 +02:00
parent dbe88fae22
commit 8b4c9459a2
No known key found for this signature in database
GPG key ID: 7E9FE9FD48F512EF
2 changed files with 22 additions and 1 deletions

View file

@ -829,7 +829,11 @@ type zeroOrOneCharacterStringMatcher struct {
func (m *zeroOrOneCharacterStringMatcher) Matches(s string) bool {
// If there's more than one rune in the string, then it can't match.
if _, size := utf8.DecodeRuneInString(s); size < len(s) {
if r, size := utf8.DecodeRuneInString(s); r == utf8.RuneError {
// Size is 0 for empty strings, 1 for invalid rune.
// Empty string matches, invalid rune matches if there isn't anything else.
return size == len(s)
} else if size < len(s) {
return false
}

View file

@ -968,6 +968,23 @@ func TestZeroOrOneCharacterStringMatcher(t *testing.T) {
require.False(t, matcher.Matches(emoji1+"x"))
require.False(t, matcher.Matches(emoji1+emoji2))
})
t.Run("invalid unicode", func(t *testing.T) {
// Just for reference, we also compare to what `^.?$` regular expression matches.
re := regexp.MustCompile("^.?$")
matcher := &zeroOrOneCharacterStringMatcher{matchNL: true}
requireMatches := func(s string, expected bool) {
t.Helper()
require.Equal(t, expected, matcher.Matches(s))
require.Equal(t, re.MatchString(s), matcher.Matches(s))
}
requireMatches("\xff", true)
requireMatches("x\xff", false)
requireMatches("\xffx", false)
requireMatches("\xff\xfe", false)
})
}
func BenchmarkZeroOrOneCharacterStringMatcher(b *testing.B) {