2017-08-08 22:19:10 +00:00
|
|
|
package dns
|
|
|
|
|
|
|
|
import (
|
2018-10-15 07:12:31 +00:00
|
|
|
"io"
|
2017-08-08 22:19:10 +00:00
|
|
|
"io/ioutil"
|
2018-06-23 08:12:44 +00:00
|
|
|
"net"
|
2017-08-08 22:19:10 +00:00
|
|
|
"os"
|
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
2018-06-23 08:12:44 +00:00
|
|
|
func TestParseZoneGenerate(t *testing.T) {
|
|
|
|
zone := "$ORIGIN example.org.\n$GENERATE 10-12 foo${2,3,d} IN A 127.0.0.$"
|
|
|
|
|
|
|
|
wantRRs := []RR{
|
|
|
|
&A{Hdr: RR_Header{Name: "foo012.example.org."}, A: net.ParseIP("127.0.0.10")},
|
|
|
|
&A{Hdr: RR_Header{Name: "foo013.example.org."}, A: net.ParseIP("127.0.0.11")},
|
|
|
|
&A{Hdr: RR_Header{Name: "foo014.example.org."}, A: net.ParseIP("127.0.0.12")},
|
|
|
|
}
|
|
|
|
wantIdx := 0
|
|
|
|
|
|
|
|
tok := ParseZone(strings.NewReader(zone), "", "")
|
|
|
|
for x := range tok {
|
|
|
|
if wantIdx >= len(wantRRs) {
|
|
|
|
t.Fatalf("expected %d RRs, but got more", len(wantRRs))
|
|
|
|
}
|
|
|
|
if x.Error != nil {
|
|
|
|
t.Fatalf("expected no error, but got %s", x.Error)
|
|
|
|
}
|
|
|
|
if got, want := x.RR.Header().Name, wantRRs[wantIdx].Header().Name; got != want {
|
|
|
|
t.Fatalf("expected name %s, but got %s", want, got)
|
|
|
|
}
|
|
|
|
a, ok := x.RR.(*A)
|
|
|
|
if !ok {
|
|
|
|
t.Fatalf("expected *A RR, but got %T", x.RR)
|
|
|
|
}
|
|
|
|
if got, want := a.A, wantRRs[wantIdx].(*A).A; !got.Equal(want) {
|
|
|
|
t.Fatalf("expected A with IP %v, but got %v", got, want)
|
|
|
|
}
|
|
|
|
wantIdx++
|
|
|
|
}
|
Add new ZoneParser API (#794)
* Improve ParseZone tests
* Add new ZoneParser API
* Use the ZoneParser API directly in ReadRR
* Merge parseZoneHelper into ParseZone
* Make generate string building slightly more efficient
* Add SetDefaultTTL method to ZoneParser
This makes it possible for external consumers to implement ReadRR.
* Make $INCLUDE directive opt-in
The $INCLUDE directive opens a user controlled file and parses it as
a DNS zone file. The error messages may reveal portions of sensitive
files, such as:
/etc/passwd: dns: not a TTL: "root:x:0:0:root:/root:/bin/bash" at line: 1:31
/etc/shadow: dns: not a TTL: "root:$6$<redacted>::0:99999:7:::" at line: 1:125
Both ParseZone and ReadRR are currently opt-in for backward
compatibility.
* Disable $INCLUDE support in ReadRR
ReadRR and NewRR are often passed untrusted input. At the same time,
$INCLUDE isn't really useful for ReadRR as it only ever returns the
first record.
This is a breaking change, but it currently represents a slight
security risk.
* Document the need to drain the ParseZone chan
* Cleanup the documentation of NewRR, ReadRR and ParseZone
* Document the ZoneParser API
* Deprecated the ParseZone function
* Add whitespace to ZoneParser.Next
* Remove prevName field from ZoneParser
This doesn't track anything meaningful as both zp.prevName and h.Name
are only ever set at the same point and to the same value.
* Use uint8 for ZoneParser.include field
It has a maximum value of 7 which easily fits within uint8.
This reduces the size of ZoneParser from 160 bytes to 152 bytes.
* Add setParseError helper to ZoneParser
* Surface $INCLUDE os.Open error in error message
* Rename ZoneParser.include field to includeDepth
* Make maximum $INCLUDE depth a const
* Add ParseZone and ZoneParser benchmarks
* Parse $GENERATE directive with a single ZoneParser
This should be more efficient than calling NewRR for each generated
record.
* Run go fmt on generate_test.go
* Add a benchmark for $GENERATE directives
* Use a custom reader for generate
This avoids the overhead and memory usage of building the zone string.
name old time/op new time/op delta
Generate-12 165µs ± 4% 157µs ± 2% -5.06% (p=0.000 n=25+25)
name old alloc/op new alloc/op delta
Generate-12 42.1kB ± 0% 31.8kB ± 0% -24.42% (p=0.000 n=20+23)
name old allocs/op new allocs/op delta
Generate-12 1.56k ± 0% 1.55k ± 0% -0.38% (p=0.000 n=25+25)
* Return correct ParseError from generateReader
The last commit made these regular errors while they had been
ParseErrors before.
* Return error message as string from modToPrintf
This is slightly simpler and they don't need to be errors.
* Skip setting includeDepth in generate
This sub parser isn't allowed to use $INCLUDE directives anyway.
Note: If generate is ever changed to allow $INCLUDE directives, then
this line must be added back. Without doing that, it would be
be possible to exceed maxIncludeDepth.
* Make generateReader errors sticky
ReadByte should not be called after an error has been returned, but
this is cheap insurance.
* Move file and lex fields to end of generateReader
These are only used for creating a ParseError and so are unlikely to be
accessed.
* Don't return offset with error in modToPrintf
Along for the ride, are some whitespace and style changes.
* Add whitespace to generate and simplify step
* Use a for loop instead of goto in generate
* Support $INCLUDE directives inside $GENERATE directives
This was previously supported and may be useful. This is now more
rigorous as the maximum include depth is respected and relative
$INCLUDE directives are now supported from within $GENERATE.
* Don't return any lexer tokens after read error
Without this, read errors are likely to be lost and become parse errors
of the remaining str. The $GENERATE code relies on surfacing errors from
the reader.
* Support $INCLUDE in NewRR and ReadRR
Removing $INCLUDE support from these is a breaking change and should
not be included in this pull request.
* Add test to ensure $GENERATE respects $INCLUDE support
* Unify TestZoneParserIncludeDisallowed with other tests
* Remove stray whitespace from TestGenerateSurfacesErrors
* Move ZoneParser SetX methods above Err method
* $GENERATE should not accept step of 0
If step is allowed to be 0, then generateReader (and the code it
replaced) will get stuck in an infinite loop.
This is a potential DOS vulnerability.
* Fix ReadRR comment for file argument
I missed this previosuly. The file argument is also used to
resolve relative $INCLUDE directives.
* Prevent test panics on nil error
* Rework ZoneParser.subNext
This is slightly cleaner and will close the underlying *os.File even
if an error occurs.
* Make ZoneParser.generate call subNext
This also moves the calls to setParseError into generate.
* Report errors when parsing rest of $GENERATE directive
* Report proper error location in $GENERATE directive
This makes error messages much clearer.
* Simplify modToPrintf func
Note: When width is 0, the leading 0 of the fmt string is now excluded.
This should not alter the formatting of numbers in anyway.
* Add comment explaining sub field
* Remove outdated error comment from generate
2018-10-20 01:17:56 +00:00
|
|
|
|
|
|
|
if wantIdx != len(wantRRs) {
|
|
|
|
t.Errorf("too few records, expected %d, got %d", len(wantRRs), wantIdx)
|
|
|
|
}
|
2018-06-23 08:12:44 +00:00
|
|
|
}
|
|
|
|
|
2017-08-08 22:19:10 +00:00
|
|
|
func TestParseZoneInclude(t *testing.T) {
|
|
|
|
|
|
|
|
tmpfile, err := ioutil.TempFile("", "dns")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("could not create tmpfile for test: %s", err)
|
|
|
|
}
|
Add new ZoneParser API (#794)
* Improve ParseZone tests
* Add new ZoneParser API
* Use the ZoneParser API directly in ReadRR
* Merge parseZoneHelper into ParseZone
* Make generate string building slightly more efficient
* Add SetDefaultTTL method to ZoneParser
This makes it possible for external consumers to implement ReadRR.
* Make $INCLUDE directive opt-in
The $INCLUDE directive opens a user controlled file and parses it as
a DNS zone file. The error messages may reveal portions of sensitive
files, such as:
/etc/passwd: dns: not a TTL: "root:x:0:0:root:/root:/bin/bash" at line: 1:31
/etc/shadow: dns: not a TTL: "root:$6$<redacted>::0:99999:7:::" at line: 1:125
Both ParseZone and ReadRR are currently opt-in for backward
compatibility.
* Disable $INCLUDE support in ReadRR
ReadRR and NewRR are often passed untrusted input. At the same time,
$INCLUDE isn't really useful for ReadRR as it only ever returns the
first record.
This is a breaking change, but it currently represents a slight
security risk.
* Document the need to drain the ParseZone chan
* Cleanup the documentation of NewRR, ReadRR and ParseZone
* Document the ZoneParser API
* Deprecated the ParseZone function
* Add whitespace to ZoneParser.Next
* Remove prevName field from ZoneParser
This doesn't track anything meaningful as both zp.prevName and h.Name
are only ever set at the same point and to the same value.
* Use uint8 for ZoneParser.include field
It has a maximum value of 7 which easily fits within uint8.
This reduces the size of ZoneParser from 160 bytes to 152 bytes.
* Add setParseError helper to ZoneParser
* Surface $INCLUDE os.Open error in error message
* Rename ZoneParser.include field to includeDepth
* Make maximum $INCLUDE depth a const
* Add ParseZone and ZoneParser benchmarks
* Parse $GENERATE directive with a single ZoneParser
This should be more efficient than calling NewRR for each generated
record.
* Run go fmt on generate_test.go
* Add a benchmark for $GENERATE directives
* Use a custom reader for generate
This avoids the overhead and memory usage of building the zone string.
name old time/op new time/op delta
Generate-12 165µs ± 4% 157µs ± 2% -5.06% (p=0.000 n=25+25)
name old alloc/op new alloc/op delta
Generate-12 42.1kB ± 0% 31.8kB ± 0% -24.42% (p=0.000 n=20+23)
name old allocs/op new allocs/op delta
Generate-12 1.56k ± 0% 1.55k ± 0% -0.38% (p=0.000 n=25+25)
* Return correct ParseError from generateReader
The last commit made these regular errors while they had been
ParseErrors before.
* Return error message as string from modToPrintf
This is slightly simpler and they don't need to be errors.
* Skip setting includeDepth in generate
This sub parser isn't allowed to use $INCLUDE directives anyway.
Note: If generate is ever changed to allow $INCLUDE directives, then
this line must be added back. Without doing that, it would be
be possible to exceed maxIncludeDepth.
* Make generateReader errors sticky
ReadByte should not be called after an error has been returned, but
this is cheap insurance.
* Move file and lex fields to end of generateReader
These are only used for creating a ParseError and so are unlikely to be
accessed.
* Don't return offset with error in modToPrintf
Along for the ride, are some whitespace and style changes.
* Add whitespace to generate and simplify step
* Use a for loop instead of goto in generate
* Support $INCLUDE directives inside $GENERATE directives
This was previously supported and may be useful. This is now more
rigorous as the maximum include depth is respected and relative
$INCLUDE directives are now supported from within $GENERATE.
* Don't return any lexer tokens after read error
Without this, read errors are likely to be lost and become parse errors
of the remaining str. The $GENERATE code relies on surfacing errors from
the reader.
* Support $INCLUDE in NewRR and ReadRR
Removing $INCLUDE support from these is a breaking change and should
not be included in this pull request.
* Add test to ensure $GENERATE respects $INCLUDE support
* Unify TestZoneParserIncludeDisallowed with other tests
* Remove stray whitespace from TestGenerateSurfacesErrors
* Move ZoneParser SetX methods above Err method
* $GENERATE should not accept step of 0
If step is allowed to be 0, then generateReader (and the code it
replaced) will get stuck in an infinite loop.
This is a potential DOS vulnerability.
* Fix ReadRR comment for file argument
I missed this previosuly. The file argument is also used to
resolve relative $INCLUDE directives.
* Prevent test panics on nil error
* Rework ZoneParser.subNext
This is slightly cleaner and will close the underlying *os.File even
if an error occurs.
* Make ZoneParser.generate call subNext
This also moves the calls to setParseError into generate.
* Report errors when parsing rest of $GENERATE directive
* Report proper error location in $GENERATE directive
This makes error messages much clearer.
* Simplify modToPrintf func
Note: When width is 0, the leading 0 of the fmt string is now excluded.
This should not alter the formatting of numbers in anyway.
* Add comment explaining sub field
* Remove outdated error comment from generate
2018-10-20 01:17:56 +00:00
|
|
|
defer os.Remove(tmpfile.Name())
|
2017-08-08 22:19:10 +00:00
|
|
|
|
|
|
|
if _, err := tmpfile.WriteString("foo\tIN\tA\t127.0.0.1"); err != nil {
|
|
|
|
t.Fatalf("unable to write content to tmpfile %q: %s", tmpfile.Name(), err)
|
|
|
|
}
|
|
|
|
if err := tmpfile.Close(); err != nil {
|
|
|
|
t.Fatalf("could not close tmpfile %q: %s", tmpfile.Name(), err)
|
|
|
|
}
|
|
|
|
|
Add new ZoneParser API (#794)
* Improve ParseZone tests
* Add new ZoneParser API
* Use the ZoneParser API directly in ReadRR
* Merge parseZoneHelper into ParseZone
* Make generate string building slightly more efficient
* Add SetDefaultTTL method to ZoneParser
This makes it possible for external consumers to implement ReadRR.
* Make $INCLUDE directive opt-in
The $INCLUDE directive opens a user controlled file and parses it as
a DNS zone file. The error messages may reveal portions of sensitive
files, such as:
/etc/passwd: dns: not a TTL: "root:x:0:0:root:/root:/bin/bash" at line: 1:31
/etc/shadow: dns: not a TTL: "root:$6$<redacted>::0:99999:7:::" at line: 1:125
Both ParseZone and ReadRR are currently opt-in for backward
compatibility.
* Disable $INCLUDE support in ReadRR
ReadRR and NewRR are often passed untrusted input. At the same time,
$INCLUDE isn't really useful for ReadRR as it only ever returns the
first record.
This is a breaking change, but it currently represents a slight
security risk.
* Document the need to drain the ParseZone chan
* Cleanup the documentation of NewRR, ReadRR and ParseZone
* Document the ZoneParser API
* Deprecated the ParseZone function
* Add whitespace to ZoneParser.Next
* Remove prevName field from ZoneParser
This doesn't track anything meaningful as both zp.prevName and h.Name
are only ever set at the same point and to the same value.
* Use uint8 for ZoneParser.include field
It has a maximum value of 7 which easily fits within uint8.
This reduces the size of ZoneParser from 160 bytes to 152 bytes.
* Add setParseError helper to ZoneParser
* Surface $INCLUDE os.Open error in error message
* Rename ZoneParser.include field to includeDepth
* Make maximum $INCLUDE depth a const
* Add ParseZone and ZoneParser benchmarks
* Parse $GENERATE directive with a single ZoneParser
This should be more efficient than calling NewRR for each generated
record.
* Run go fmt on generate_test.go
* Add a benchmark for $GENERATE directives
* Use a custom reader for generate
This avoids the overhead and memory usage of building the zone string.
name old time/op new time/op delta
Generate-12 165µs ± 4% 157µs ± 2% -5.06% (p=0.000 n=25+25)
name old alloc/op new alloc/op delta
Generate-12 42.1kB ± 0% 31.8kB ± 0% -24.42% (p=0.000 n=20+23)
name old allocs/op new allocs/op delta
Generate-12 1.56k ± 0% 1.55k ± 0% -0.38% (p=0.000 n=25+25)
* Return correct ParseError from generateReader
The last commit made these regular errors while they had been
ParseErrors before.
* Return error message as string from modToPrintf
This is slightly simpler and they don't need to be errors.
* Skip setting includeDepth in generate
This sub parser isn't allowed to use $INCLUDE directives anyway.
Note: If generate is ever changed to allow $INCLUDE directives, then
this line must be added back. Without doing that, it would be
be possible to exceed maxIncludeDepth.
* Make generateReader errors sticky
ReadByte should not be called after an error has been returned, but
this is cheap insurance.
* Move file and lex fields to end of generateReader
These are only used for creating a ParseError and so are unlikely to be
accessed.
* Don't return offset with error in modToPrintf
Along for the ride, are some whitespace and style changes.
* Add whitespace to generate and simplify step
* Use a for loop instead of goto in generate
* Support $INCLUDE directives inside $GENERATE directives
This was previously supported and may be useful. This is now more
rigorous as the maximum include depth is respected and relative
$INCLUDE directives are now supported from within $GENERATE.
* Don't return any lexer tokens after read error
Without this, read errors are likely to be lost and become parse errors
of the remaining str. The $GENERATE code relies on surfacing errors from
the reader.
* Support $INCLUDE in NewRR and ReadRR
Removing $INCLUDE support from these is a breaking change and should
not be included in this pull request.
* Add test to ensure $GENERATE respects $INCLUDE support
* Unify TestZoneParserIncludeDisallowed with other tests
* Remove stray whitespace from TestGenerateSurfacesErrors
* Move ZoneParser SetX methods above Err method
* $GENERATE should not accept step of 0
If step is allowed to be 0, then generateReader (and the code it
replaced) will get stuck in an infinite loop.
This is a potential DOS vulnerability.
* Fix ReadRR comment for file argument
I missed this previosuly. The file argument is also used to
resolve relative $INCLUDE directives.
* Prevent test panics on nil error
* Rework ZoneParser.subNext
This is slightly cleaner and will close the underlying *os.File even
if an error occurs.
* Make ZoneParser.generate call subNext
This also moves the calls to setParseError into generate.
* Report errors when parsing rest of $GENERATE directive
* Report proper error location in $GENERATE directive
This makes error messages much clearer.
* Simplify modToPrintf func
Note: When width is 0, the leading 0 of the fmt string is now excluded.
This should not alter the formatting of numbers in anyway.
* Add comment explaining sub field
* Remove outdated error comment from generate
2018-10-20 01:17:56 +00:00
|
|
|
zone := "$ORIGIN example.org.\n$INCLUDE " + tmpfile.Name() + "\nbar\tIN\tA\t127.0.0.2"
|
2017-08-08 22:19:10 +00:00
|
|
|
|
Add new ZoneParser API (#794)
* Improve ParseZone tests
* Add new ZoneParser API
* Use the ZoneParser API directly in ReadRR
* Merge parseZoneHelper into ParseZone
* Make generate string building slightly more efficient
* Add SetDefaultTTL method to ZoneParser
This makes it possible for external consumers to implement ReadRR.
* Make $INCLUDE directive opt-in
The $INCLUDE directive opens a user controlled file and parses it as
a DNS zone file. The error messages may reveal portions of sensitive
files, such as:
/etc/passwd: dns: not a TTL: "root:x:0:0:root:/root:/bin/bash" at line: 1:31
/etc/shadow: dns: not a TTL: "root:$6$<redacted>::0:99999:7:::" at line: 1:125
Both ParseZone and ReadRR are currently opt-in for backward
compatibility.
* Disable $INCLUDE support in ReadRR
ReadRR and NewRR are often passed untrusted input. At the same time,
$INCLUDE isn't really useful for ReadRR as it only ever returns the
first record.
This is a breaking change, but it currently represents a slight
security risk.
* Document the need to drain the ParseZone chan
* Cleanup the documentation of NewRR, ReadRR and ParseZone
* Document the ZoneParser API
* Deprecated the ParseZone function
* Add whitespace to ZoneParser.Next
* Remove prevName field from ZoneParser
This doesn't track anything meaningful as both zp.prevName and h.Name
are only ever set at the same point and to the same value.
* Use uint8 for ZoneParser.include field
It has a maximum value of 7 which easily fits within uint8.
This reduces the size of ZoneParser from 160 bytes to 152 bytes.
* Add setParseError helper to ZoneParser
* Surface $INCLUDE os.Open error in error message
* Rename ZoneParser.include field to includeDepth
* Make maximum $INCLUDE depth a const
* Add ParseZone and ZoneParser benchmarks
* Parse $GENERATE directive with a single ZoneParser
This should be more efficient than calling NewRR for each generated
record.
* Run go fmt on generate_test.go
* Add a benchmark for $GENERATE directives
* Use a custom reader for generate
This avoids the overhead and memory usage of building the zone string.
name old time/op new time/op delta
Generate-12 165µs ± 4% 157µs ± 2% -5.06% (p=0.000 n=25+25)
name old alloc/op new alloc/op delta
Generate-12 42.1kB ± 0% 31.8kB ± 0% -24.42% (p=0.000 n=20+23)
name old allocs/op new allocs/op delta
Generate-12 1.56k ± 0% 1.55k ± 0% -0.38% (p=0.000 n=25+25)
* Return correct ParseError from generateReader
The last commit made these regular errors while they had been
ParseErrors before.
* Return error message as string from modToPrintf
This is slightly simpler and they don't need to be errors.
* Skip setting includeDepth in generate
This sub parser isn't allowed to use $INCLUDE directives anyway.
Note: If generate is ever changed to allow $INCLUDE directives, then
this line must be added back. Without doing that, it would be
be possible to exceed maxIncludeDepth.
* Make generateReader errors sticky
ReadByte should not be called after an error has been returned, but
this is cheap insurance.
* Move file and lex fields to end of generateReader
These are only used for creating a ParseError and so are unlikely to be
accessed.
* Don't return offset with error in modToPrintf
Along for the ride, are some whitespace and style changes.
* Add whitespace to generate and simplify step
* Use a for loop instead of goto in generate
* Support $INCLUDE directives inside $GENERATE directives
This was previously supported and may be useful. This is now more
rigorous as the maximum include depth is respected and relative
$INCLUDE directives are now supported from within $GENERATE.
* Don't return any lexer tokens after read error
Without this, read errors are likely to be lost and become parse errors
of the remaining str. The $GENERATE code relies on surfacing errors from
the reader.
* Support $INCLUDE in NewRR and ReadRR
Removing $INCLUDE support from these is a breaking change and should
not be included in this pull request.
* Add test to ensure $GENERATE respects $INCLUDE support
* Unify TestZoneParserIncludeDisallowed with other tests
* Remove stray whitespace from TestGenerateSurfacesErrors
* Move ZoneParser SetX methods above Err method
* $GENERATE should not accept step of 0
If step is allowed to be 0, then generateReader (and the code it
replaced) will get stuck in an infinite loop.
This is a potential DOS vulnerability.
* Fix ReadRR comment for file argument
I missed this previosuly. The file argument is also used to
resolve relative $INCLUDE directives.
* Prevent test panics on nil error
* Rework ZoneParser.subNext
This is slightly cleaner and will close the underlying *os.File even
if an error occurs.
* Make ZoneParser.generate call subNext
This also moves the calls to setParseError into generate.
* Report errors when parsing rest of $GENERATE directive
* Report proper error location in $GENERATE directive
This makes error messages much clearer.
* Simplify modToPrintf func
Note: When width is 0, the leading 0 of the fmt string is now excluded.
This should not alter the formatting of numbers in anyway.
* Add comment explaining sub field
* Remove outdated error comment from generate
2018-10-20 01:17:56 +00:00
|
|
|
var got int
|
2017-08-08 22:19:10 +00:00
|
|
|
tok := ParseZone(strings.NewReader(zone), "", "")
|
|
|
|
for x := range tok {
|
|
|
|
if x.Error != nil {
|
|
|
|
t.Fatalf("expected no error, but got %s", x.Error)
|
|
|
|
}
|
Add new ZoneParser API (#794)
* Improve ParseZone tests
* Add new ZoneParser API
* Use the ZoneParser API directly in ReadRR
* Merge parseZoneHelper into ParseZone
* Make generate string building slightly more efficient
* Add SetDefaultTTL method to ZoneParser
This makes it possible for external consumers to implement ReadRR.
* Make $INCLUDE directive opt-in
The $INCLUDE directive opens a user controlled file and parses it as
a DNS zone file. The error messages may reveal portions of sensitive
files, such as:
/etc/passwd: dns: not a TTL: "root:x:0:0:root:/root:/bin/bash" at line: 1:31
/etc/shadow: dns: not a TTL: "root:$6$<redacted>::0:99999:7:::" at line: 1:125
Both ParseZone and ReadRR are currently opt-in for backward
compatibility.
* Disable $INCLUDE support in ReadRR
ReadRR and NewRR are often passed untrusted input. At the same time,
$INCLUDE isn't really useful for ReadRR as it only ever returns the
first record.
This is a breaking change, but it currently represents a slight
security risk.
* Document the need to drain the ParseZone chan
* Cleanup the documentation of NewRR, ReadRR and ParseZone
* Document the ZoneParser API
* Deprecated the ParseZone function
* Add whitespace to ZoneParser.Next
* Remove prevName field from ZoneParser
This doesn't track anything meaningful as both zp.prevName and h.Name
are only ever set at the same point and to the same value.
* Use uint8 for ZoneParser.include field
It has a maximum value of 7 which easily fits within uint8.
This reduces the size of ZoneParser from 160 bytes to 152 bytes.
* Add setParseError helper to ZoneParser
* Surface $INCLUDE os.Open error in error message
* Rename ZoneParser.include field to includeDepth
* Make maximum $INCLUDE depth a const
* Add ParseZone and ZoneParser benchmarks
* Parse $GENERATE directive with a single ZoneParser
This should be more efficient than calling NewRR for each generated
record.
* Run go fmt on generate_test.go
* Add a benchmark for $GENERATE directives
* Use a custom reader for generate
This avoids the overhead and memory usage of building the zone string.
name old time/op new time/op delta
Generate-12 165µs ± 4% 157µs ± 2% -5.06% (p=0.000 n=25+25)
name old alloc/op new alloc/op delta
Generate-12 42.1kB ± 0% 31.8kB ± 0% -24.42% (p=0.000 n=20+23)
name old allocs/op new allocs/op delta
Generate-12 1.56k ± 0% 1.55k ± 0% -0.38% (p=0.000 n=25+25)
* Return correct ParseError from generateReader
The last commit made these regular errors while they had been
ParseErrors before.
* Return error message as string from modToPrintf
This is slightly simpler and they don't need to be errors.
* Skip setting includeDepth in generate
This sub parser isn't allowed to use $INCLUDE directives anyway.
Note: If generate is ever changed to allow $INCLUDE directives, then
this line must be added back. Without doing that, it would be
be possible to exceed maxIncludeDepth.
* Make generateReader errors sticky
ReadByte should not be called after an error has been returned, but
this is cheap insurance.
* Move file and lex fields to end of generateReader
These are only used for creating a ParseError and so are unlikely to be
accessed.
* Don't return offset with error in modToPrintf
Along for the ride, are some whitespace and style changes.
* Add whitespace to generate and simplify step
* Use a for loop instead of goto in generate
* Support $INCLUDE directives inside $GENERATE directives
This was previously supported and may be useful. This is now more
rigorous as the maximum include depth is respected and relative
$INCLUDE directives are now supported from within $GENERATE.
* Don't return any lexer tokens after read error
Without this, read errors are likely to be lost and become parse errors
of the remaining str. The $GENERATE code relies on surfacing errors from
the reader.
* Support $INCLUDE in NewRR and ReadRR
Removing $INCLUDE support from these is a breaking change and should
not be included in this pull request.
* Add test to ensure $GENERATE respects $INCLUDE support
* Unify TestZoneParserIncludeDisallowed with other tests
* Remove stray whitespace from TestGenerateSurfacesErrors
* Move ZoneParser SetX methods above Err method
* $GENERATE should not accept step of 0
If step is allowed to be 0, then generateReader (and the code it
replaced) will get stuck in an infinite loop.
This is a potential DOS vulnerability.
* Fix ReadRR comment for file argument
I missed this previosuly. The file argument is also used to
resolve relative $INCLUDE directives.
* Prevent test panics on nil error
* Rework ZoneParser.subNext
This is slightly cleaner and will close the underlying *os.File even
if an error occurs.
* Make ZoneParser.generate call subNext
This also moves the calls to setParseError into generate.
* Report errors when parsing rest of $GENERATE directive
* Report proper error location in $GENERATE directive
This makes error messages much clearer.
* Simplify modToPrintf func
Note: When width is 0, the leading 0 of the fmt string is now excluded.
This should not alter the formatting of numbers in anyway.
* Add comment explaining sub field
* Remove outdated error comment from generate
2018-10-20 01:17:56 +00:00
|
|
|
switch x.RR.Header().Name {
|
|
|
|
case "foo.example.org.", "bar.example.org.":
|
|
|
|
default:
|
|
|
|
t.Fatalf("expected foo.example.org. or bar.example.org., but got %s", x.RR.Header().Name)
|
2017-08-18 13:14:42 +00:00
|
|
|
}
|
Add new ZoneParser API (#794)
* Improve ParseZone tests
* Add new ZoneParser API
* Use the ZoneParser API directly in ReadRR
* Merge parseZoneHelper into ParseZone
* Make generate string building slightly more efficient
* Add SetDefaultTTL method to ZoneParser
This makes it possible for external consumers to implement ReadRR.
* Make $INCLUDE directive opt-in
The $INCLUDE directive opens a user controlled file and parses it as
a DNS zone file. The error messages may reveal portions of sensitive
files, such as:
/etc/passwd: dns: not a TTL: "root:x:0:0:root:/root:/bin/bash" at line: 1:31
/etc/shadow: dns: not a TTL: "root:$6$<redacted>::0:99999:7:::" at line: 1:125
Both ParseZone and ReadRR are currently opt-in for backward
compatibility.
* Disable $INCLUDE support in ReadRR
ReadRR and NewRR are often passed untrusted input. At the same time,
$INCLUDE isn't really useful for ReadRR as it only ever returns the
first record.
This is a breaking change, but it currently represents a slight
security risk.
* Document the need to drain the ParseZone chan
* Cleanup the documentation of NewRR, ReadRR and ParseZone
* Document the ZoneParser API
* Deprecated the ParseZone function
* Add whitespace to ZoneParser.Next
* Remove prevName field from ZoneParser
This doesn't track anything meaningful as both zp.prevName and h.Name
are only ever set at the same point and to the same value.
* Use uint8 for ZoneParser.include field
It has a maximum value of 7 which easily fits within uint8.
This reduces the size of ZoneParser from 160 bytes to 152 bytes.
* Add setParseError helper to ZoneParser
* Surface $INCLUDE os.Open error in error message
* Rename ZoneParser.include field to includeDepth
* Make maximum $INCLUDE depth a const
* Add ParseZone and ZoneParser benchmarks
* Parse $GENERATE directive with a single ZoneParser
This should be more efficient than calling NewRR for each generated
record.
* Run go fmt on generate_test.go
* Add a benchmark for $GENERATE directives
* Use a custom reader for generate
This avoids the overhead and memory usage of building the zone string.
name old time/op new time/op delta
Generate-12 165µs ± 4% 157µs ± 2% -5.06% (p=0.000 n=25+25)
name old alloc/op new alloc/op delta
Generate-12 42.1kB ± 0% 31.8kB ± 0% -24.42% (p=0.000 n=20+23)
name old allocs/op new allocs/op delta
Generate-12 1.56k ± 0% 1.55k ± 0% -0.38% (p=0.000 n=25+25)
* Return correct ParseError from generateReader
The last commit made these regular errors while they had been
ParseErrors before.
* Return error message as string from modToPrintf
This is slightly simpler and they don't need to be errors.
* Skip setting includeDepth in generate
This sub parser isn't allowed to use $INCLUDE directives anyway.
Note: If generate is ever changed to allow $INCLUDE directives, then
this line must be added back. Without doing that, it would be
be possible to exceed maxIncludeDepth.
* Make generateReader errors sticky
ReadByte should not be called after an error has been returned, but
this is cheap insurance.
* Move file and lex fields to end of generateReader
These are only used for creating a ParseError and so are unlikely to be
accessed.
* Don't return offset with error in modToPrintf
Along for the ride, are some whitespace and style changes.
* Add whitespace to generate and simplify step
* Use a for loop instead of goto in generate
* Support $INCLUDE directives inside $GENERATE directives
This was previously supported and may be useful. This is now more
rigorous as the maximum include depth is respected and relative
$INCLUDE directives are now supported from within $GENERATE.
* Don't return any lexer tokens after read error
Without this, read errors are likely to be lost and become parse errors
of the remaining str. The $GENERATE code relies on surfacing errors from
the reader.
* Support $INCLUDE in NewRR and ReadRR
Removing $INCLUDE support from these is a breaking change and should
not be included in this pull request.
* Add test to ensure $GENERATE respects $INCLUDE support
* Unify TestZoneParserIncludeDisallowed with other tests
* Remove stray whitespace from TestGenerateSurfacesErrors
* Move ZoneParser SetX methods above Err method
* $GENERATE should not accept step of 0
If step is allowed to be 0, then generateReader (and the code it
replaced) will get stuck in an infinite loop.
This is a potential DOS vulnerability.
* Fix ReadRR comment for file argument
I missed this previosuly. The file argument is also used to
resolve relative $INCLUDE directives.
* Prevent test panics on nil error
* Rework ZoneParser.subNext
This is slightly cleaner and will close the underlying *os.File even
if an error occurs.
* Make ZoneParser.generate call subNext
This also moves the calls to setParseError into generate.
* Report errors when parsing rest of $GENERATE directive
* Report proper error location in $GENERATE directive
This makes error messages much clearer.
* Simplify modToPrintf func
Note: When width is 0, the leading 0 of the fmt string is now excluded.
This should not alter the formatting of numbers in anyway.
* Add comment explaining sub field
* Remove outdated error comment from generate
2018-10-20 01:17:56 +00:00
|
|
|
got++
|
|
|
|
}
|
|
|
|
|
|
|
|
if expected := 2; got != expected {
|
|
|
|
t.Errorf("failed to parse zone after include, expected %d records, got %d", expected, got)
|
2017-08-08 22:19:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
os.Remove(tmpfile.Name())
|
|
|
|
|
|
|
|
tok = ParseZone(strings.NewReader(zone), "", "")
|
|
|
|
for x := range tok {
|
|
|
|
if x.Error == nil {
|
|
|
|
t.Fatalf("expected first token to contain an error but it didn't")
|
|
|
|
}
|
|
|
|
if !strings.Contains(x.Error.Error(), "failed to open") ||
|
Add new ZoneParser API (#794)
* Improve ParseZone tests
* Add new ZoneParser API
* Use the ZoneParser API directly in ReadRR
* Merge parseZoneHelper into ParseZone
* Make generate string building slightly more efficient
* Add SetDefaultTTL method to ZoneParser
This makes it possible for external consumers to implement ReadRR.
* Make $INCLUDE directive opt-in
The $INCLUDE directive opens a user controlled file and parses it as
a DNS zone file. The error messages may reveal portions of sensitive
files, such as:
/etc/passwd: dns: not a TTL: "root:x:0:0:root:/root:/bin/bash" at line: 1:31
/etc/shadow: dns: not a TTL: "root:$6$<redacted>::0:99999:7:::" at line: 1:125
Both ParseZone and ReadRR are currently opt-in for backward
compatibility.
* Disable $INCLUDE support in ReadRR
ReadRR and NewRR are often passed untrusted input. At the same time,
$INCLUDE isn't really useful for ReadRR as it only ever returns the
first record.
This is a breaking change, but it currently represents a slight
security risk.
* Document the need to drain the ParseZone chan
* Cleanup the documentation of NewRR, ReadRR and ParseZone
* Document the ZoneParser API
* Deprecated the ParseZone function
* Add whitespace to ZoneParser.Next
* Remove prevName field from ZoneParser
This doesn't track anything meaningful as both zp.prevName and h.Name
are only ever set at the same point and to the same value.
* Use uint8 for ZoneParser.include field
It has a maximum value of 7 which easily fits within uint8.
This reduces the size of ZoneParser from 160 bytes to 152 bytes.
* Add setParseError helper to ZoneParser
* Surface $INCLUDE os.Open error in error message
* Rename ZoneParser.include field to includeDepth
* Make maximum $INCLUDE depth a const
* Add ParseZone and ZoneParser benchmarks
* Parse $GENERATE directive with a single ZoneParser
This should be more efficient than calling NewRR for each generated
record.
* Run go fmt on generate_test.go
* Add a benchmark for $GENERATE directives
* Use a custom reader for generate
This avoids the overhead and memory usage of building the zone string.
name old time/op new time/op delta
Generate-12 165µs ± 4% 157µs ± 2% -5.06% (p=0.000 n=25+25)
name old alloc/op new alloc/op delta
Generate-12 42.1kB ± 0% 31.8kB ± 0% -24.42% (p=0.000 n=20+23)
name old allocs/op new allocs/op delta
Generate-12 1.56k ± 0% 1.55k ± 0% -0.38% (p=0.000 n=25+25)
* Return correct ParseError from generateReader
The last commit made these regular errors while they had been
ParseErrors before.
* Return error message as string from modToPrintf
This is slightly simpler and they don't need to be errors.
* Skip setting includeDepth in generate
This sub parser isn't allowed to use $INCLUDE directives anyway.
Note: If generate is ever changed to allow $INCLUDE directives, then
this line must be added back. Without doing that, it would be
be possible to exceed maxIncludeDepth.
* Make generateReader errors sticky
ReadByte should not be called after an error has been returned, but
this is cheap insurance.
* Move file and lex fields to end of generateReader
These are only used for creating a ParseError and so are unlikely to be
accessed.
* Don't return offset with error in modToPrintf
Along for the ride, are some whitespace and style changes.
* Add whitespace to generate and simplify step
* Use a for loop instead of goto in generate
* Support $INCLUDE directives inside $GENERATE directives
This was previously supported and may be useful. This is now more
rigorous as the maximum include depth is respected and relative
$INCLUDE directives are now supported from within $GENERATE.
* Don't return any lexer tokens after read error
Without this, read errors are likely to be lost and become parse errors
of the remaining str. The $GENERATE code relies on surfacing errors from
the reader.
* Support $INCLUDE in NewRR and ReadRR
Removing $INCLUDE support from these is a breaking change and should
not be included in this pull request.
* Add test to ensure $GENERATE respects $INCLUDE support
* Unify TestZoneParserIncludeDisallowed with other tests
* Remove stray whitespace from TestGenerateSurfacesErrors
* Move ZoneParser SetX methods above Err method
* $GENERATE should not accept step of 0
If step is allowed to be 0, then generateReader (and the code it
replaced) will get stuck in an infinite loop.
This is a potential DOS vulnerability.
* Fix ReadRR comment for file argument
I missed this previosuly. The file argument is also used to
resolve relative $INCLUDE directives.
* Prevent test panics on nil error
* Rework ZoneParser.subNext
This is slightly cleaner and will close the underlying *os.File even
if an error occurs.
* Make ZoneParser.generate call subNext
This also moves the calls to setParseError into generate.
* Report errors when parsing rest of $GENERATE directive
* Report proper error location in $GENERATE directive
This makes error messages much clearer.
* Simplify modToPrintf func
Note: When width is 0, the leading 0 of the fmt string is now excluded.
This should not alter the formatting of numbers in anyway.
* Add comment explaining sub field
* Remove outdated error comment from generate
2018-10-20 01:17:56 +00:00
|
|
|
!strings.Contains(x.Error.Error(), tmpfile.Name()) ||
|
|
|
|
!strings.Contains(x.Error.Error(), "no such file or directory") {
|
|
|
|
t.Fatalf(`expected error to contain: "failed to open", %q and "no such file or directory" but got: %s`,
|
|
|
|
tmpfile.Name(), x.Error)
|
2017-08-08 22:19:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-09-22 17:36:01 +00:00
|
|
|
|
Add new ZoneParser API (#794)
* Improve ParseZone tests
* Add new ZoneParser API
* Use the ZoneParser API directly in ReadRR
* Merge parseZoneHelper into ParseZone
* Make generate string building slightly more efficient
* Add SetDefaultTTL method to ZoneParser
This makes it possible for external consumers to implement ReadRR.
* Make $INCLUDE directive opt-in
The $INCLUDE directive opens a user controlled file and parses it as
a DNS zone file. The error messages may reveal portions of sensitive
files, such as:
/etc/passwd: dns: not a TTL: "root:x:0:0:root:/root:/bin/bash" at line: 1:31
/etc/shadow: dns: not a TTL: "root:$6$<redacted>::0:99999:7:::" at line: 1:125
Both ParseZone and ReadRR are currently opt-in for backward
compatibility.
* Disable $INCLUDE support in ReadRR
ReadRR and NewRR are often passed untrusted input. At the same time,
$INCLUDE isn't really useful for ReadRR as it only ever returns the
first record.
This is a breaking change, but it currently represents a slight
security risk.
* Document the need to drain the ParseZone chan
* Cleanup the documentation of NewRR, ReadRR and ParseZone
* Document the ZoneParser API
* Deprecated the ParseZone function
* Add whitespace to ZoneParser.Next
* Remove prevName field from ZoneParser
This doesn't track anything meaningful as both zp.prevName and h.Name
are only ever set at the same point and to the same value.
* Use uint8 for ZoneParser.include field
It has a maximum value of 7 which easily fits within uint8.
This reduces the size of ZoneParser from 160 bytes to 152 bytes.
* Add setParseError helper to ZoneParser
* Surface $INCLUDE os.Open error in error message
* Rename ZoneParser.include field to includeDepth
* Make maximum $INCLUDE depth a const
* Add ParseZone and ZoneParser benchmarks
* Parse $GENERATE directive with a single ZoneParser
This should be more efficient than calling NewRR for each generated
record.
* Run go fmt on generate_test.go
* Add a benchmark for $GENERATE directives
* Use a custom reader for generate
This avoids the overhead and memory usage of building the zone string.
name old time/op new time/op delta
Generate-12 165µs ± 4% 157µs ± 2% -5.06% (p=0.000 n=25+25)
name old alloc/op new alloc/op delta
Generate-12 42.1kB ± 0% 31.8kB ± 0% -24.42% (p=0.000 n=20+23)
name old allocs/op new allocs/op delta
Generate-12 1.56k ± 0% 1.55k ± 0% -0.38% (p=0.000 n=25+25)
* Return correct ParseError from generateReader
The last commit made these regular errors while they had been
ParseErrors before.
* Return error message as string from modToPrintf
This is slightly simpler and they don't need to be errors.
* Skip setting includeDepth in generate
This sub parser isn't allowed to use $INCLUDE directives anyway.
Note: If generate is ever changed to allow $INCLUDE directives, then
this line must be added back. Without doing that, it would be
be possible to exceed maxIncludeDepth.
* Make generateReader errors sticky
ReadByte should not be called after an error has been returned, but
this is cheap insurance.
* Move file and lex fields to end of generateReader
These are only used for creating a ParseError and so are unlikely to be
accessed.
* Don't return offset with error in modToPrintf
Along for the ride, are some whitespace and style changes.
* Add whitespace to generate and simplify step
* Use a for loop instead of goto in generate
* Support $INCLUDE directives inside $GENERATE directives
This was previously supported and may be useful. This is now more
rigorous as the maximum include depth is respected and relative
$INCLUDE directives are now supported from within $GENERATE.
* Don't return any lexer tokens after read error
Without this, read errors are likely to be lost and become parse errors
of the remaining str. The $GENERATE code relies on surfacing errors from
the reader.
* Support $INCLUDE in NewRR and ReadRR
Removing $INCLUDE support from these is a breaking change and should
not be included in this pull request.
* Add test to ensure $GENERATE respects $INCLUDE support
* Unify TestZoneParserIncludeDisallowed with other tests
* Remove stray whitespace from TestGenerateSurfacesErrors
* Move ZoneParser SetX methods above Err method
* $GENERATE should not accept step of 0
If step is allowed to be 0, then generateReader (and the code it
replaced) will get stuck in an infinite loop.
This is a potential DOS vulnerability.
* Fix ReadRR comment for file argument
I missed this previosuly. The file argument is also used to
resolve relative $INCLUDE directives.
* Prevent test panics on nil error
* Rework ZoneParser.subNext
This is slightly cleaner and will close the underlying *os.File even
if an error occurs.
* Make ZoneParser.generate call subNext
This also moves the calls to setParseError into generate.
* Report errors when parsing rest of $GENERATE directive
* Report proper error location in $GENERATE directive
This makes error messages much clearer.
* Simplify modToPrintf func
Note: When width is 0, the leading 0 of the fmt string is now excluded.
This should not alter the formatting of numbers in anyway.
* Add comment explaining sub field
* Remove outdated error comment from generate
2018-10-20 01:17:56 +00:00
|
|
|
func TestZoneParserIncludeDisallowed(t *testing.T) {
|
|
|
|
tmpfile, err := ioutil.TempFile("", "dns")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("could not create tmpfile for test: %s", err)
|
|
|
|
}
|
|
|
|
defer os.Remove(tmpfile.Name())
|
|
|
|
|
|
|
|
if _, err := tmpfile.WriteString("foo\tIN\tA\t127.0.0.1"); err != nil {
|
|
|
|
t.Fatalf("unable to write content to tmpfile %q: %s", tmpfile.Name(), err)
|
|
|
|
}
|
|
|
|
if err := tmpfile.Close(); err != nil {
|
|
|
|
t.Fatalf("could not close tmpfile %q: %s", tmpfile.Name(), err)
|
|
|
|
}
|
|
|
|
|
|
|
|
zp := NewZoneParser(strings.NewReader("$INCLUDE "+tmpfile.Name()), "example.org.", "")
|
|
|
|
|
|
|
|
for _, ok := zp.Next(); ok; _, ok = zp.Next() {
|
|
|
|
}
|
|
|
|
|
|
|
|
const expect = "$INCLUDE directive not allowed"
|
|
|
|
if err := zp.Err(); err == nil || !strings.Contains(err.Error(), expect) {
|
|
|
|
t.Errorf("expected error to contain %q, got %v", expect, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-22 17:36:01 +00:00
|
|
|
func TestParseTA(t *testing.T) {
|
|
|
|
rr, err := NewRR(` Ta 0 0 0`)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("expected no error, but got %s", err)
|
|
|
|
}
|
|
|
|
if rr == nil {
|
|
|
|
t.Fatal(`expected a normal RR, but got nil`)
|
|
|
|
}
|
|
|
|
}
|
2018-10-15 07:12:31 +00:00
|
|
|
|
|
|
|
var errTestReadError = &Error{"test error"}
|
|
|
|
|
|
|
|
type errReader struct{}
|
|
|
|
|
|
|
|
func (errReader) Read(p []byte) (int, error) { return 0, errTestReadError }
|
|
|
|
|
|
|
|
func TestParseZoneReadError(t *testing.T) {
|
|
|
|
rr, err := ReadRR(errReader{}, "")
|
|
|
|
if err == nil || !strings.Contains(err.Error(), errTestReadError.Error()) {
|
|
|
|
t.Errorf("expected error to contain %q, but got %v", errTestReadError, err)
|
|
|
|
}
|
|
|
|
if rr != nil {
|
|
|
|
t.Errorf("expected a nil RR, but got %v", rr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkNewRR(b *testing.B) {
|
|
|
|
const name1 = "12345678901234567890123456789012345.12345678.123."
|
|
|
|
const s = name1 + " 3600 IN MX 10 " + name1
|
|
|
|
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
_, err := NewRR(s)
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkReadRR(b *testing.B) {
|
|
|
|
const name1 = "12345678901234567890123456789012345.12345678.123."
|
|
|
|
const s = name1 + " 3600 IN MX 10 " + name1 + "\n"
|
|
|
|
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
r := struct{ io.Reader }{strings.NewReader(s)}
|
|
|
|
// r is now only an io.Reader and won't benefit from the
|
|
|
|
// io.ByteReader special-case in zlexer.Next.
|
|
|
|
|
|
|
|
_, err := ReadRR(r, "")
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
Add new ZoneParser API (#794)
* Improve ParseZone tests
* Add new ZoneParser API
* Use the ZoneParser API directly in ReadRR
* Merge parseZoneHelper into ParseZone
* Make generate string building slightly more efficient
* Add SetDefaultTTL method to ZoneParser
This makes it possible for external consumers to implement ReadRR.
* Make $INCLUDE directive opt-in
The $INCLUDE directive opens a user controlled file and parses it as
a DNS zone file. The error messages may reveal portions of sensitive
files, such as:
/etc/passwd: dns: not a TTL: "root:x:0:0:root:/root:/bin/bash" at line: 1:31
/etc/shadow: dns: not a TTL: "root:$6$<redacted>::0:99999:7:::" at line: 1:125
Both ParseZone and ReadRR are currently opt-in for backward
compatibility.
* Disable $INCLUDE support in ReadRR
ReadRR and NewRR are often passed untrusted input. At the same time,
$INCLUDE isn't really useful for ReadRR as it only ever returns the
first record.
This is a breaking change, but it currently represents a slight
security risk.
* Document the need to drain the ParseZone chan
* Cleanup the documentation of NewRR, ReadRR and ParseZone
* Document the ZoneParser API
* Deprecated the ParseZone function
* Add whitespace to ZoneParser.Next
* Remove prevName field from ZoneParser
This doesn't track anything meaningful as both zp.prevName and h.Name
are only ever set at the same point and to the same value.
* Use uint8 for ZoneParser.include field
It has a maximum value of 7 which easily fits within uint8.
This reduces the size of ZoneParser from 160 bytes to 152 bytes.
* Add setParseError helper to ZoneParser
* Surface $INCLUDE os.Open error in error message
* Rename ZoneParser.include field to includeDepth
* Make maximum $INCLUDE depth a const
* Add ParseZone and ZoneParser benchmarks
* Parse $GENERATE directive with a single ZoneParser
This should be more efficient than calling NewRR for each generated
record.
* Run go fmt on generate_test.go
* Add a benchmark for $GENERATE directives
* Use a custom reader for generate
This avoids the overhead and memory usage of building the zone string.
name old time/op new time/op delta
Generate-12 165µs ± 4% 157µs ± 2% -5.06% (p=0.000 n=25+25)
name old alloc/op new alloc/op delta
Generate-12 42.1kB ± 0% 31.8kB ± 0% -24.42% (p=0.000 n=20+23)
name old allocs/op new allocs/op delta
Generate-12 1.56k ± 0% 1.55k ± 0% -0.38% (p=0.000 n=25+25)
* Return correct ParseError from generateReader
The last commit made these regular errors while they had been
ParseErrors before.
* Return error message as string from modToPrintf
This is slightly simpler and they don't need to be errors.
* Skip setting includeDepth in generate
This sub parser isn't allowed to use $INCLUDE directives anyway.
Note: If generate is ever changed to allow $INCLUDE directives, then
this line must be added back. Without doing that, it would be
be possible to exceed maxIncludeDepth.
* Make generateReader errors sticky
ReadByte should not be called after an error has been returned, but
this is cheap insurance.
* Move file and lex fields to end of generateReader
These are only used for creating a ParseError and so are unlikely to be
accessed.
* Don't return offset with error in modToPrintf
Along for the ride, are some whitespace and style changes.
* Add whitespace to generate and simplify step
* Use a for loop instead of goto in generate
* Support $INCLUDE directives inside $GENERATE directives
This was previously supported and may be useful. This is now more
rigorous as the maximum include depth is respected and relative
$INCLUDE directives are now supported from within $GENERATE.
* Don't return any lexer tokens after read error
Without this, read errors are likely to be lost and become parse errors
of the remaining str. The $GENERATE code relies on surfacing errors from
the reader.
* Support $INCLUDE in NewRR and ReadRR
Removing $INCLUDE support from these is a breaking change and should
not be included in this pull request.
* Add test to ensure $GENERATE respects $INCLUDE support
* Unify TestZoneParserIncludeDisallowed with other tests
* Remove stray whitespace from TestGenerateSurfacesErrors
* Move ZoneParser SetX methods above Err method
* $GENERATE should not accept step of 0
If step is allowed to be 0, then generateReader (and the code it
replaced) will get stuck in an infinite loop.
This is a potential DOS vulnerability.
* Fix ReadRR comment for file argument
I missed this previosuly. The file argument is also used to
resolve relative $INCLUDE directives.
* Prevent test panics on nil error
* Rework ZoneParser.subNext
This is slightly cleaner and will close the underlying *os.File even
if an error occurs.
* Make ZoneParser.generate call subNext
This also moves the calls to setParseError into generate.
* Report errors when parsing rest of $GENERATE directive
* Report proper error location in $GENERATE directive
This makes error messages much clearer.
* Simplify modToPrintf func
Note: When width is 0, the leading 0 of the fmt string is now excluded.
This should not alter the formatting of numbers in anyway.
* Add comment explaining sub field
* Remove outdated error comment from generate
2018-10-20 01:17:56 +00:00
|
|
|
|
|
|
|
const benchZone = `
|
|
|
|
foo. IN A 10.0.0.1 ; this is comment 1
|
|
|
|
foo. IN A (
|
|
|
|
10.0.0.2 ; this is comment 2
|
|
|
|
)
|
|
|
|
; this is comment 3
|
|
|
|
foo. IN A 10.0.0.3
|
|
|
|
foo. IN A ( 10.0.0.4 ); this is comment 4
|
|
|
|
|
|
|
|
foo. IN A 10.0.0.5
|
|
|
|
; this is comment 5
|
|
|
|
|
|
|
|
foo. IN A 10.0.0.6
|
|
|
|
|
|
|
|
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
|
|
|
|
`
|
|
|
|
|
|
|
|
func BenchmarkParseZone(b *testing.B) {
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
for tok := range ParseZone(strings.NewReader(benchZone), "example.org.", "") {
|
|
|
|
if tok.Error != nil {
|
|
|
|
b.Fatal(tok.Error)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkZoneParser(b *testing.B) {
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
zp := NewZoneParser(strings.NewReader(benchZone), "example.org.", "")
|
|
|
|
|
|
|
|
for _, ok := zp.Next(); ok; _, ok = zp.Next() {
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := zp.Err(); err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|