mirror of
https://github.com/miekg/dns.git
synced 2025-08-11 20:16:58 +02:00
* txt parser: fix goroutine leak When a higher level (grammar or syntax) error was encountered the lower level zlexer routine would be left open and trying to send more tokens on the channel c. This leaks a goroutine, per failed parse... This PR fixes this by signalling this error - by canceling a context - retrieving any remaining items from the channel, so zlexer can return. It also adds a goroutine leak test that can be re-used in other tests, the TestParseBadNAPTR test uses this leak detector. The private key parsing code had the same bug and is also fixed in this PR. Fixes #586 Fixes https://github.com/coredns/coredns/issues/1233 * sem not needed anymore
57 lines
1.0 KiB
Go
57 lines
1.0 KiB
Go
package dns
|
|
|
|
// Implement a simple scanner, return a byte stream from an io reader.
|
|
|
|
import (
|
|
"bufio"
|
|
"context"
|
|
"io"
|
|
"text/scanner"
|
|
)
|
|
|
|
type scan struct {
|
|
src *bufio.Reader
|
|
position scanner.Position
|
|
eof bool // Have we just seen a eof
|
|
ctx context.Context
|
|
}
|
|
|
|
func scanInit(r io.Reader) (*scan, context.CancelFunc) {
|
|
s := new(scan)
|
|
s.src = bufio.NewReader(r)
|
|
s.position.Line = 1
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
s.ctx = ctx
|
|
|
|
return s, cancel
|
|
}
|
|
|
|
// tokenText returns the next byte from the input
|
|
func (s *scan) tokenText() (byte, error) {
|
|
c, err := s.src.ReadByte()
|
|
if err != nil {
|
|
return c, err
|
|
}
|
|
select {
|
|
case <-s.ctx.Done():
|
|
return c, context.Canceled
|
|
default:
|
|
break
|
|
}
|
|
|
|
// delay the newline handling until the next token is delivered,
|
|
// fixes off-by-one errors when reporting a parse error.
|
|
if s.eof == true {
|
|
s.position.Line++
|
|
s.position.Column = 0
|
|
s.eof = false
|
|
}
|
|
if c == '\n' {
|
|
s.eof = true
|
|
return c, nil
|
|
}
|
|
s.position.Column++
|
|
return c, nil
|
|
}
|