Skip to content

Commit

Permalink
refactor: remove ParseZone and parseZone (#1099)
Browse files Browse the repository at this point in the history
  • Loading branch information
taciomcosta authored Apr 28, 2020
1 parent 5bfe94b commit d128d10
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 161 deletions.
21 changes: 11 additions & 10 deletions generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,22 +62,23 @@ $GENERATE 0-1/0 dhcp-${0,4,d} A 10.0.0.$
{`@ IN SOA ns.test. hostmaster.test. ( 1 8h 2h 7d 1d )
$GENERATE 0-1 $$INCLUDE ` + tmpdir + string(filepath.Separator) + `${0,4,d}.conf
`, false},
{`@ IN SOA ns.test. hostmaster.test. ( 1 8h 2h 7d 1d )
{`@ IN SOA ns.test. hostmaster.test. ( 1 8h 2h 7d 1d )
$GENERATE 0-1 dhcp-${0,4,d} A 10.0.0.$
$GENERATE 0-2 dhcp-${0,4,d} A 10.1.0.$
`, false},
}
Outer:

for i := range tests {
for tok := range ParseZone(strings.NewReader(tests[i].zone), "test.", "test") {
if tok.Error != nil {
if !tests[i].fail {
t.Errorf("expected \n\n%s\nto be parsed, but got %v", tests[i].zone, tok.Error)
}
continue Outer
}
z := NewZoneParser(strings.NewReader(tests[i].zone), "test.", "test")
z.SetIncludeAllowed(true)

for _, ok := z.Next(); ok; _, ok = z.Next() {
}
if tests[i].fail {

err := z.Err()
if err != nil && !tests[i].fail {
t.Errorf("expected \n\n%s\nto be parsed, but got %v", tests[i].zone, err)
} else if err == nil && tests[i].fail {
t.Errorf("expected \n\n%s\nto fail, but got no error", tests[i].zone)
}
}
Expand Down
71 changes: 37 additions & 34 deletions parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -546,25 +546,25 @@ $TTL 314
example.com. DNAME 10 ; TTL=314 after second $TTL
`
reCaseFromComment := regexp.MustCompile(`TTL=(\d+)\s+(.*)`)
records := ParseZone(strings.NewReader(zone), "", "")
z := NewZoneParser(strings.NewReader(zone), "", "")
var i int
for record := range records {

for rr, ok := z.Next(); ok; rr, ok = z.Next() {
i++
if record.Error != nil {
t.Error(record.Error)
continue
}
expected := reCaseFromComment.FindStringSubmatch(record.Comment)
expected := reCaseFromComment.FindStringSubmatch(z.Comment())
if len(expected) != 3 {
t.Errorf("regexp didn't match for record %d", i)
continue
}
expectedTTL, _ := strconv.ParseUint(expected[1], 10, 32)
ttl := record.RR.Header().Ttl
ttl := rr.Header().Ttl
if ttl != uint32(expectedTTL) {
t.Errorf("%s: expected TTL %d, got %d", expected[2], expectedTTL, ttl)
}
}
if err := z.Err(); err != nil {
t.Error(err)
}
if i != 10 {
t.Errorf("expected %d records, got %d", 5, i)
}
Expand Down Expand Up @@ -603,16 +603,12 @@ func TestRelativeNameErrors(t *testing.T) {
},
}
for _, errorCase := range badZones {
entries := ParseZone(strings.NewReader(errorCase.zoneContents), "", "")
for entry := range entries {
if entry.Error == nil {
t.Errorf("%s: expected error, got nil", errorCase.label)
continue
}
err := entry.Error.err
if err != errorCase.expectedErr {
t.Errorf("%s: expected error `%s`, got `%s`", errorCase.label, errorCase.expectedErr, err)
}
z := NewZoneParser(strings.NewReader(errorCase.zoneContents), "", "")
z.Next()
if err := z.Err(); err == nil {
t.Errorf("%s: expected error, got nil", errorCase.label)
} else if !strings.Contains(err.Error(), errorCase.expectedErr) {
t.Errorf("%s: expected error `%s`, got `%s`", errorCase.label, errorCase.expectedErr, err)
}
}
}
Expand Down Expand Up @@ -719,9 +715,13 @@ func TestRfc1982(t *testing.T) {
}

func TestEmpty(t *testing.T) {
for range ParseZone(strings.NewReader(""), "", "") {
z := NewZoneParser(strings.NewReader(""), "", "")
for _, ok := z.Next(); ok; _, ok = z.Next() {
t.Errorf("should be empty")
}
if err := z.Err(); err != nil {
t.Error("got an error when it shouldn't")
}
}

func TestLowercaseTokens(t *testing.T) {
Expand Down Expand Up @@ -889,18 +889,20 @@ foo. IN DNSKEY 256 3 5 AwEAAb+8l ; this is comment 6
foo. IN NSEC miek.nl. TXT RRSIG NSEC; this is comment 7
foo. IN TXT "THIS IS TEXT MAN"; this is comment 8
`
for x := range ParseZone(strings.NewReader(zone), ".", "") {
if x.Error == nil {
if x.Comment != "" {
if _, ok := comments[x.Comment]; !ok {
t.Errorf("wrong comment %q", x.Comment)
}
z := NewZoneParser(strings.NewReader(zone), ".", "")
for _, ok := z.Next(); ok; _, ok = z.Next() {
if z.Comment() != "" {
if _, okC := comments[z.Comment()]; !okC {
t.Errorf("wrong comment %q", z.Comment())
}
}
}
if err := z.Err(); err != nil {
t.Error("got an error when it shouldn't")
}
}

func TestParseZoneComments(t *testing.T) {
func TestZoneParserComments(t *testing.T) {
for i, test := range []struct {
zone string
comments []string
Expand Down Expand Up @@ -975,24 +977,25 @@ func TestParseZoneComments(t *testing.T) {
r := strings.NewReader(test.zone)

var j int
for r := range ParseZone(r, "", "") {
if r.Error != nil {
t.Fatal(r.Error)
}

z := NewZoneParser(r, "", "")
for rr, ok := z.Next(); ok; rr, ok = z.Next() {
if j >= len(test.comments) {
t.Fatalf("too many records for zone %d at %d record, expected %d", i, j+1, len(test.comments))
}

if r.Comment != test.comments[j] {
t.Errorf("invalid comment for record %d:%d %v / %v", i, j, r.RR, r.Error)
if z.Comment() != test.comments[j] {
t.Errorf("invalid comment for record %d:%d %v", i, j, rr)
t.Logf("expected %q", test.comments[j])
t.Logf("got %q", r.Comment)
t.Logf("got %q", z.Comment())
}

j++
}

if err := z.Err(); err != nil {
t.Fatal(err)
}

if j != len(test.comments) {
t.Errorf("too few records for zone %d, got %d, expected %d", i, j, len(test.comments))
}
Expand Down
10 changes: 6 additions & 4 deletions privaterr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,11 @@ func TestPrivateZoneParser(t *testing.T) {
defer dns.PrivateHandleRemove(TypeVERSION)

r := strings.NewReader(smallzone)
for x := range dns.ParseZone(r, ".", "") {
if err := x.Error; err != nil {
t.Fatal(err)
}
z := dns.NewZoneParser(r, ".", "")

for _, ok := z.Next(); ok; _, ok = z.Next() {
}
if err := z.Err(); err != nil {
t.Fatal(err)
}
}
74 changes: 0 additions & 74 deletions scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,16 +87,6 @@ type lex struct {
column int // column in the file
}

// Token holds the token that are returned when a zone file is parsed.
type Token struct {
// The scanned resource record when error is not nil.
RR
// When an error occurred, this has the error specifics.
Error *ParseError
// A potential comment positioned after the RR and on the same line.
Comment string
}

// ttlState describes the state necessary to fill in an omitted RR TTL
type ttlState struct {
ttl uint32 // ttl is the current default TTL
Expand Down Expand Up @@ -130,70 +120,6 @@ func ReadRR(r io.Reader, file string) (RR, error) {
return rr, zp.Err()
}

// ParseZone reads a RFC 1035 style zonefile from r. It returns
// Tokens on the returned channel, each consisting of either a
// parsed RR and optional comment or a nil RR and an error. The
// channel is closed by ParseZone when the end of r is reached.
//
// The string file is used in error reporting and to resolve relative
// $INCLUDE directives. The string origin is used as the initial
// origin, as if the file would start with an $ORIGIN directive.
//
// The directives $INCLUDE, $ORIGIN, $TTL and $GENERATE are all
// supported. Note that $GENERATE's range support up to a maximum of
// of 65535 steps.
//
// Basic usage pattern when reading from a string (z) containing the
// zone data:
//
// for x := range dns.ParseZone(strings.NewReader(z), "", "") {
// if x.Error != nil {
// // log.Println(x.Error)
// } else {
// // Do something with x.RR
// }
// }
//
// Comments specified after an RR (and on the same line!) are
// returned too:
//
// foo. IN A 10.0.0.1 ; this is a comment
//
// The text "; this is comment" is returned in Token.Comment.
// Comments inside the RR are returned concatenated along with the
// RR. Comments on a line by themselves are discarded.
//
// To prevent memory leaks it is important to always fully drain the
// returned channel. If an error occurs, it will always be the last
// Token sent on the channel.
//
// Deprecated: New users should prefer the ZoneParser API.
func ParseZone(r io.Reader, origin, file string) chan *Token {
t := make(chan *Token, 10000)
go parseZone(r, origin, file, t)
return t
}

func parseZone(r io.Reader, origin, file string, t chan *Token) {
defer close(t)

zp := NewZoneParser(r, origin, file)
zp.SetIncludeAllowed(true)

for rr, ok := zp.Next(); ok; rr, ok = zp.Next() {
t <- &Token{RR: rr, Comment: zp.Comment()}
}

if err := zp.Err(); err != nil {
pe, ok := err.(*ParseError)
if !ok {
pe = &ParseError{file: file, err: err.Error()}
}

t <- &Token{Error: pe}
}
}

// ZoneParser is a parser for an RFC 1035 style zonefile.
//
// Each parsed RR in the zone is returned sequentially from Next. An
Expand Down
Loading

0 comments on commit d128d10

Please sign in to comment.