64 lines
2.0 KiB
Diff
64 lines
2.0 KiB
Diff
--- CHANGELOG.md
|
|
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
|
### Fixed
|
|
|
|
+- Fixed a non-terminating loop in the selector lexer when tokenizing unterminated regex patterns (e.g. `r/abc`). The tokenizer now returns an error instead of looping indefinitely.
|
|
- Fix panic when selector query contains a trailing backslash in a quoted string ([GHSA-m5j3-4634-c2vq](https://github.com/TomWright/dasel/security/advisories/GHSA-m5j3-4634-c2vq)).
|
|
|
|
## [v3.10.0] - 2026-05-13
|
|
|
|
--- selector/lexer/tokenize.go
|
|
@@ -271,17 +271,20 @@ func (p *Tokenizer) parseCurRune() (Token, error) {
|
|
return ptr.To(NewToken(kind, other, pos, l))
|
|
}
|
|
|
|
- matchRegexPattern := func(pos int) *Token {
|
|
+ matchRegexPattern := func(pos int) (*Token, error) {
|
|
if p.src[pos] != 'r' || !p.peekRuneEqual(pos+1, '/') {
|
|
- return nil
|
|
+ return nil, nil
|
|
}
|
|
start := pos
|
|
pos += 2
|
|
- for !p.peekRuneEqual(pos, '/') {
|
|
+ for pos < p.srcLen && p.src[pos] != '/' {
|
|
pos++
|
|
}
|
|
+ if pos >= p.srcLen {
|
|
+ return nil, &UnexpectedEOFError{Pos: pos}
|
|
+ }
|
|
pos++
|
|
- return ptr.To(NewToken(RegexPattern, p.src[start+2:pos-1], start, pos-start))
|
|
+ return ptr.To(NewToken(RegexPattern, p.src[start+2:pos-1], start, pos-start)), nil
|
|
}
|
|
|
|
if t := matchStr(pos, "null", true, Null); t != nil {
|
|
@@ -345,7 +348,10 @@ func (p *Tokenizer) parseCurRune() (Token, error) {
|
|
return *t, nil
|
|
}
|
|
|
|
- if t := matchRegexPattern(pos); t != nil {
|
|
+ if t, err := matchRegexPattern(pos); t != nil || err != nil {
|
|
+ if err != nil {
|
|
+ return Token{}, err
|
|
+ }
|
|
return *t, nil
|
|
}
|
|
|
|
|
|
--- selector/lexer/tokenize_test.go
|
|
@@ -181,5 +181,13 @@ func TestTokenizer_Parse(t *testing.T) {
|
|
in: `'\`,
|
|
match: matchUnexpectedEOFError(2),
|
|
}.run)
|
|
+ t.Run("unterminated regex", errTestCase{
|
|
+ in: `r/unterminated`,
|
|
+ match: matchUnexpectedEOFError(14),
|
|
+ }.run)
|
|
+ t.Run("unterminated regex minimal", errTestCase{
|
|
+ in: `r/`,
|
|
+ match: matchUnexpectedEOFError(2),
|
|
+ }.run)
|
|
})
|
|
}
|