From c0283a2028317d3fb6574f9a06e68443cf6b89cd Mon Sep 17 00:00:00 2001 From: Alexey Naidyonov Date: Fri, 5 Oct 2018 20:30:27 +0300 Subject: [PATCH] Allows larger offset in $GENERATE (#776) Although BIND9 documentations does not specify the possible size of offset in $GENERATE clause, it clearly says that range must be a positive integer between 0 and (2^31)-1. Moreover, BIND perfectly supports large offsets which might be really handy when you're dealing with large intranets. I.e. consider following case ``` $GENERATE 0-255 dhcp-${0,4,d} A 10.0.0.$ $GENERATE 0-255 dhcp-${256,4,d} A 10.0.1.$ $GENERATE 0-255 dhcp-${512,4,d} A 10.0.2.$ ... ``` This change removes offset size check and introduces check that 0 >= (start + offset) and (end + offset) < (2^31)-1. --- generate.go | 4 +++- generate_test.go | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/generate.go b/generate.go index 3a559793..91d928c8 100644 --- a/generate.go +++ b/generate.go @@ -107,6 +107,8 @@ BuildRR: mod, offset, err = modToPrintf(s[j+2 : j+2+sep]) if err != nil { return err.Error() + } else if start + offset < 0 || end + offset > 1<<31-1 { + return "bad offset in $GENERATE" } j += 2 + sep // Jump to it } @@ -152,7 +154,7 @@ func modToPrintf(s string) (string, int, error) { return "", 0, errors.New("bad base in $GENERATE") } offset, err := strconv.Atoi(xs[0]) - if err != nil || offset > 255 { + if err != nil { return "", 0, errors.New("bad offset in $GENERATE") } width, err := strconv.Atoi(xs[1]) diff --git a/generate_test.go b/generate_test.go index 1df6abd6..e224c1b8 100644 --- a/generate_test.go +++ b/generate_test.go @@ -2,8 +2,46 @@ package dns import ( "testing" + "strings" ) +func TestGenerateRangeGuard(t *testing.T) { + var tests = [...]struct { + zone string + fail bool + }{{ + `@ IN SOA ns.test. hostmaster.test. ( 1 8h 2h 7d 1d ) +$GENERATE 0-1 dhcp-${0,4,d} A 10.0.0.$ +`, false},{ + `@ IN SOA ns.test. hostmaster.test. ( 1 8h 2h 7d 1d ) +$GENERATE 128-129 dhcp-${-128,4,d} A 10.0.0.$ +`, false},{ + `@ IN SOA ns.test. hostmaster.test. ( 1 8h 2h 7d 1d ) +$GENERATE 128-129 dhcp-${-129,4,d} A 10.0.0.$ +`, true},{ + `@ IN SOA ns.test. hostmaster.test. ( 1 8h 2h 7d 1d ) +$GENERATE 0-2 dhcp-${2147483647,4,d} A 10.0.0.$ +`, true},{ + `@ IN SOA ns.test. hostmaster.test. ( 1 8h 2h 7d 1d ) +$GENERATE 0-1 dhcp-${2147483646,4,d} A 10.0.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 + } + } + if tests[i].fail { + t.Errorf("expected \n\n%s\nto fail, but got no error", tests[i].zone) + } + } +} + func TestGenerateModToPrintf(t *testing.T) { tests := []struct { mod string @@ -22,6 +60,7 @@ func TestGenerateModToPrintf(t *testing.T) { {"0,0,X", "%0X", 0, false}, {"0,0,z", "", 0, true}, {"0,0,0,d", "", 0, true}, + {"-100,0,d", "%0d", -100, false}, } for _, test := range tests { gotFmt, gotOffset, err := modToPrintf(test.mod)