From f40b966c4720a3f596ba670ae7f9a670d8db41a4 Mon Sep 17 00:00:00 2001 From: Alex Sergeyev Date: Wed, 27 Aug 2014 16:27:37 -0400 Subject: [PATCH 01/11] Added lowercase RRClass and RRType tests per #108. ... need to add RRSIG covering type lowercased later. --- parse_test.go | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/parse_test.go b/parse_test.go index 12de8224..daddd619 100644 --- a/parse_test.go +++ b/parse_test.go @@ -761,6 +761,21 @@ func TestEmpty(t *testing.T) { } } +func TestLowercaseClassOrType(t *testing.T) { + var testrecords = []string{ + "example.org. IN a 1.2.3.4", + "example.org. in A 1.2.3.4", + "example.org. in a 1.2.3.4", + "example.org. a 1.2.3.4", + } + for _, testrr := range testrecords { + _, err := NewRR(testrr) + if err != nil { + t.Errorf("failed to parse %#v, got %s", testrr, err.Error()) + } + } +} + func ExampleGenerate() { // From the manual: http://www.bind9.net/manual/bind/9.3.2/Bv9ARM.ch06.html#id2566761 zone := "$GENERATE 1-2 0 NS SERVER$.EXAMPLE.\n$GENERATE 1-8 $ CNAME $.0" @@ -1051,7 +1066,12 @@ func TestTXT(t *testing.T) { func TestTypeXXXX(t *testing.T) { _, err := NewRR("example.com IN TYPE1234 \\# 4 aabbccdd") if err != nil { - t.Logf("failed to parse TYPE1234 RR: ", err.Error()) + t.Logf("failed to parse TYPE1234 RR: %s", err.Error()) + t.Fail() + } + _, err = NewRR("example.com IN type1234 \\# 4 aabbccdd") + if err != nil { + t.Logf("failed to parse type1234 RR: %s", err.Error()) t.Fail() } _, err = NewRR("example.com IN TYPE655341 \\# 8 aabbccddaabbccdd") From 0df460c0face8636dd385cc3dd765cc6cf83dbf3 Mon Sep 17 00:00:00 2001 From: Alex Sergeyev Date: Wed, 27 Aug 2014 16:36:28 -0400 Subject: [PATCH 02/11] Added lowercase RR tests where TTL is in play too. --- parse_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/parse_test.go b/parse_test.go index daddd619..34c3172c 100644 --- a/parse_test.go +++ b/parse_test.go @@ -763,6 +763,10 @@ func TestEmpty(t *testing.T) { func TestLowercaseClassOrType(t *testing.T) { var testrecords = []string{ + "example.org. 300 IN a 1.2.3.4", + "example.org. 300 in A 1.2.3.4", + "example.org. 300 in a 1.2.3.4", + "example.org. 300 a 1.2.3.4", "example.org. IN a 1.2.3.4", "example.org. in A 1.2.3.4", "example.org. in a 1.2.3.4", From e9bffe67966a8b1610f06db01af9353d40222d65 Mon Sep 17 00:00:00 2001 From: Alex Sergeyev Date: Wed, 27 Aug 2014 16:38:31 -0400 Subject: [PATCH 03/11] Added lowercase test strings with RR class omitted --- parse_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/parse_test.go b/parse_test.go index 34c3172c..f309978f 100644 --- a/parse_test.go +++ b/parse_test.go @@ -767,10 +767,13 @@ func TestLowercaseClassOrType(t *testing.T) { "example.org. 300 in A 1.2.3.4", "example.org. 300 in a 1.2.3.4", "example.org. 300 a 1.2.3.4", + "example.org. 300 A 1.2.3.4", "example.org. IN a 1.2.3.4", "example.org. in A 1.2.3.4", "example.org. in a 1.2.3.4", "example.org. a 1.2.3.4", + "example.org. A 1.2.3.4", + "example.org. a 1.2.3.4", } for _, testrr := range testrecords { _, err := NewRR(testrr) From 755a8483b6b7ba58e8fa89fceee5762bda49b2aa Mon Sep 17 00:00:00 2001 From: Alex Sergeyev Date: Thu, 28 Aug 2014 08:00:15 -0400 Subject: [PATCH 04/11] Committing @miekg patch from gist. https://gist.github.com/miekg/f1b1fe6dba7d6b088eec --- parse_test.go | 2 +- zscan.go | 26 ++++++++++++++------------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/parse_test.go b/parse_test.go index f309978f..3b6e946a 100644 --- a/parse_test.go +++ b/parse_test.go @@ -1071,7 +1071,7 @@ func TestTXT(t *testing.T) { } func TestTypeXXXX(t *testing.T) { - _, err := NewRR("example.com IN TYPE1234 \\# 4 aabbccdd") + _, err := NewRR("example.com IN type1234 \\# 4 aabbccdd") if err != nil { t.Logf("failed to parse TYPE1234 RR: %s", err.Error()) t.Fail() diff --git a/zscan.go b/zscan.go index 7a935736..433c8bc3 100644 --- a/zscan.go +++ b/zscan.go @@ -88,14 +88,15 @@ func (e *ParseError) Error() (s string) { } type lex struct { - token string // text of the token - length int // lenght of the token - err bool // when true, token text has lexer error - value uint8 // value: _STRING, _BLANK, etc. - line int // line in the file - column int // column in the file - torc uint16 // type or class as parsed in the lexer, we only need to look this up in the grammar - comment string // any comment text seen + token string // text of the token + tokenUpper string // uppercase text of the token + length int // lenght of the token + err bool // when true, token text has lexer error + value uint8 // value: _STRING, _BLANK, etc. + line int // line in the file + column int // column in the file + torc uint16 // type or class as parsed in the lexer, we only need to look this up in the grammar + comment string // any comment text seen } // *Tokens are returned when a zone file is parsed. @@ -553,14 +554,15 @@ func zlexer(s *scan, c chan lex) { } else { l.value = _STRING l.token = string(str[:stri]) + l.tokenUpper = strings.ToUpper(l.token) l.length = stri if !rrtype { - if t, ok := StringToType[l.token]; ok { + if t, ok := StringToType[l.tokenUpper]; ok { l.value = _RRTYPE l.torc = t rrtype = true } else { - if strings.HasPrefix(l.token, "TYPE") { + if strings.HasPrefix(l.tokenUpper, "TYPE") { if t, ok := typeToInt(l.token); !ok { l.token = "unknown RR type" l.err = true @@ -572,11 +574,11 @@ func zlexer(s *scan, c chan lex) { } } } - if t, ok := StringToClass[l.token]; ok { + if t, ok := StringToClass[l.tokenUpper]; ok { l.value = _CLASS l.torc = t } else { - if strings.HasPrefix(l.token, "CLASS") { + if strings.HasPrefix(l.tokenUpper, "CLASS") { if t, ok := classToInt(l.token); !ok { l.token = "unknown class" l.err = true From 66342f4ea2e3c89f04fdf8d1ca7f049f1de4f14a Mon Sep 17 00:00:00 2001 From: Alex Sergeyev Date: Thu, 28 Aug 2014 08:04:33 -0400 Subject: [PATCH 05/11] Added test to verify RRSIG type covered in mixed case. --- parse_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/parse_test.go b/parse_test.go index 3b6e946a..a9686b14 100644 --- a/parse_test.go +++ b/parse_test.go @@ -336,6 +336,7 @@ func TestNSEC(t *testing.T) { "p2209hipbpnm681knjnu0m1febshlv4e.nl. IN NSEC3 1 1 5 30923C44C6CBBB8F P90DG1KE8QEAN0B01613LHQDG0SOJ0TA NS SOA TXT RRSIG DNSKEY NSEC3PARAM": "p2209hipbpnm681knjnu0m1febshlv4e.nl.\t3600\tIN\tNSEC3\t1 1 5 30923C44C6CBBB8F P90DG1KE8QEAN0B01613LHQDG0SOJ0TA NS SOA TXT RRSIG DNSKEY NSEC3PARAM", "localhost.dnssex.nl. IN NSEC www.dnssex.nl. A RRSIG NSEC": "localhost.dnssex.nl.\t3600\tIN\tNSEC\twww.dnssex.nl. A RRSIG NSEC", "localhost.dnssex.nl. IN NSEC www.dnssex.nl. A RRSIG NSEC TYPE65534": "localhost.dnssex.nl.\t3600\tIN\tNSEC\twww.dnssex.nl. A RRSIG NSEC TYPE65534", + "localhost.dnssex.nl. IN NSEC www.dnssex.nl. A RRSIG NSec Type65534": "localhost.dnssex.nl.\t3600\tIN\tNSEC\twww.dnssex.nl. A RRSIG NSEC TYPE65534", } for i, o := range nsectests { rr, e := NewRR(i) From d1ea8497adf63e8a5b5b83ced2afe04a467d07b9 Mon Sep 17 00:00:00 2001 From: Alex Sergeyev Date: Thu, 28 Aug 2014 08:11:18 -0400 Subject: [PATCH 06/11] Added couple failure tests for lowercase class/type --- parse_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/parse_test.go b/parse_test.go index a9686b14..393adfa6 100644 --- a/parse_test.go +++ b/parse_test.go @@ -514,6 +514,8 @@ func TestParseFailure(t *testing.T) { "miek.nl. IN AAAA ::x", "miek.nl. IN MX a0 miek.nl.", "miek.nl aap IN MX mx.miek.nl.", + "miek.nl 200 IN mxx 10 mx.miek.nl.", + "miek.nl. inn MX 10 mx.miek.nl.", // "miek.nl. IN CNAME ", // actually valid nowadays, zero size rdata "miek.nl. IN CNAME ..", "miek.nl. PA MX 10 miek.nl.", From 476d12203021dabd00452c7fd13bf33a169d5fdd Mon Sep 17 00:00:00 2001 From: Alex Sergeyev Date: Thu, 28 Aug 2014 08:17:40 -0400 Subject: [PATCH 07/11] Changed test for lowercase tokens; improved code: * for cases if $ORIGIN or $TTL are used in mixed case * changed test name too --- parse_test.go | 5 ++++- zscan.go | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/parse_test.go b/parse_test.go index 393adfa6..3f7cec0e 100644 --- a/parse_test.go +++ b/parse_test.go @@ -764,7 +764,7 @@ func TestEmpty(t *testing.T) { } } -func TestLowercaseClassOrType(t *testing.T) { +func TestLowercaseTockens(t *testing.T) { var testrecords = []string{ "example.org. 300 IN a 1.2.3.4", "example.org. 300 in A 1.2.3.4", @@ -777,6 +777,9 @@ func TestLowercaseClassOrType(t *testing.T) { "example.org. a 1.2.3.4", "example.org. A 1.2.3.4", "example.org. a 1.2.3.4", + "$ORIGIN example.org.\n a 1.2.3.4", + "$Origin example.org.\n a 1.2.3.4", + "$origin example.org.\n a 1.2.3.4", } for _, testrr := range testrecords { _, err := NewRR(testrr) diff --git a/zscan.go b/zscan.go index 433c8bc3..e051d8e5 100644 --- a/zscan.go +++ b/zscan.go @@ -537,9 +537,10 @@ func zlexer(s *scan, c chan lex) { // If we have a string and its the first, make it an owner l.value = _OWNER l.token = string(str[:stri]) + l.tokenUpper = strings.ToUpper(l.token) l.length = stri // escape $... start with a \ not a $, so this will work - switch l.token { + switch l.tokenUpper { case "$TTL": l.value = _DIRTTL case "$ORIGIN": From 84d9ad0a399bbc063e4dccb2b021a9e5a9e3a07b Mon Sep 17 00:00:00 2001 From: Alex Sergeyev Date: Thu, 28 Aug 2014 08:27:09 -0400 Subject: [PATCH 08/11] Fixed typo in "tokens" --- parse_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parse_test.go b/parse_test.go index 3f7cec0e..17ec3ace 100644 --- a/parse_test.go +++ b/parse_test.go @@ -764,7 +764,7 @@ func TestEmpty(t *testing.T) { } } -func TestLowercaseTockens(t *testing.T) { +func TestLowercaseTokens(t *testing.T) { var testrecords = []string{ "example.org. 300 IN a 1.2.3.4", "example.org. 300 in A 1.2.3.4", From 9c4dca35d564168d8c7ae4862766c3d83482d63b Mon Sep 17 00:00:00 2001 From: Alex Sergeyev Date: Thu, 28 Aug 2014 08:33:06 -0400 Subject: [PATCH 09/11] Removed unnecessary toUpper. --- zscan_rr.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zscan_rr.go b/zscan_rr.go index dc553855..42f488f1 100644 --- a/zscan_rr.go +++ b/zscan_rr.go @@ -1145,8 +1145,8 @@ func setRRSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { rr := new(RRSIG) rr.Hdr = h l := <-c - if t, ok := StringToType[strings.ToUpper(l.token)]; !ok { - if strings.HasPrefix(strings.ToUpper(l.token), "TYPE") { + if t, ok := StringToType[l.tokenUpper]; !ok { + if strings.HasPrefix(l.tokenUpper, "TYPE") { if t, ok = typeToInt(l.token); !ok { return nil, &ParseError{f, "bad RRSIG Typecovered", l}, "" } else { From 1959cc84219bf2970c70b651666c19c6ffb8c29b Mon Sep 17 00:00:00 2001 From: Alex Sergeyev Date: Thu, 28 Aug 2014 13:05:05 -0400 Subject: [PATCH 10/11] Added tests to support mixed case Type and Class --- parse_test.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/parse_test.go b/parse_test.go index 17ec3ace..ab9f37e9 100644 --- a/parse_test.go +++ b/parse_test.go @@ -780,6 +780,7 @@ func TestLowercaseTokens(t *testing.T) { "$ORIGIN example.org.\n a 1.2.3.4", "$Origin example.org.\n a 1.2.3.4", "$origin example.org.\n a 1.2.3.4", + "example.org. Class1 Type1 1.2.3.4", } for _, testrr := range testrecords { _, err := NewRR(testrr) @@ -1077,16 +1078,11 @@ func TestTXT(t *testing.T) { } func TestTypeXXXX(t *testing.T) { - _, err := NewRR("example.com IN type1234 \\# 4 aabbccdd") + _, err := NewRR("example.com IN TYPE1234 \\# 4 aabbccdd") if err != nil { t.Logf("failed to parse TYPE1234 RR: %s", err.Error()) t.Fail() } - _, err = NewRR("example.com IN type1234 \\# 4 aabbccdd") - if err != nil { - t.Logf("failed to parse type1234 RR: %s", err.Error()) - t.Fail() - } _, err = NewRR("example.com IN TYPE655341 \\# 8 aabbccddaabbccdd") if err == nil { t.Logf("this should not work, for TYPE655341") From 05bec3968af02201d7de062038cb176d365c9210 Mon Sep 17 00:00:00 2001 From: Alex Sergeyev Date: Thu, 28 Aug 2014 13:34:00 -0400 Subject: [PATCH 11/11] Addressed cases when tokenUpper makes sense to be used. --- zscan.go | 4 +++- zscan_rr.go | 18 +++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/zscan.go b/zscan.go index e051d8e5..91df3429 100644 --- a/zscan.go +++ b/zscan.go @@ -671,9 +671,11 @@ func zlexer(s *scan, c chan lex) { if stri != 0 { l.value = _STRING l.token = string(str[:stri]) + l.tokenUpper = strings.ToUpper(l.token) + l.length = stri if !rrtype { - if t, ok := StringToType[strings.ToUpper(l.token)]; ok { + if t, ok := StringToType[l.tokenUpper]; ok { l.value = _RRTYPE l.torc = t rrtype = true diff --git a/zscan_rr.go b/zscan_rr.go index 42f488f1..c58c91c6 100644 --- a/zscan_rr.go +++ b/zscan_rr.go @@ -1147,7 +1147,7 @@ func setRRSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { l := <-c if t, ok := StringToType[l.tokenUpper]; !ok { if strings.HasPrefix(l.tokenUpper, "TYPE") { - if t, ok = typeToInt(l.token); !ok { + if t, ok = typeToInt(l.tokenUpper); !ok { return nil, &ParseError{f, "bad RRSIG Typecovered", l}, "" } else { rr.TypeCovered = t @@ -1261,8 +1261,8 @@ func setNSEC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { case _BLANK: // Ok case _STRING: - if k, ok = StringToType[strings.ToUpper(l.token)]; !ok { - if k, ok = typeToInt(l.token); !ok { + if k, ok = StringToType[l.tokenUpper]; !ok { + if k, ok = typeToInt(l.tokenUpper); !ok { return nil, &ParseError{f, "bad NSEC TypeBitMap", l}, "" } } @@ -1323,8 +1323,8 @@ func setNSEC3(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { case _BLANK: // Ok case _STRING: - if k, ok = StringToType[strings.ToUpper(l.token)]; !ok { - if k, ok = typeToInt(l.token); !ok { + if k, ok = StringToType[l.tokenUpper]; !ok { + if k, ok = typeToInt(l.tokenUpper); !ok { return nil, &ParseError{f, "bad NSEC3 TypeBitMap", l}, "" } } @@ -1580,7 +1580,7 @@ func setDS(h RR_Header, c chan lex, f string) (RR, *ParseError, string) { <-c // _BLANK l = <-c if i, e := strconv.Atoi(l.token); e != nil { - if i, ok := StringToAlgorithm[strings.ToUpper(l.token)]; !ok { + if i, ok := StringToAlgorithm[l.tokenUpper]; !ok { return nil, &ParseError{f, "bad DS Algorithm", l}, "" } else { rr.Algorithm = i @@ -1681,7 +1681,7 @@ func setCDS(h RR_Header, c chan lex, f string) (RR, *ParseError, string) { <-c // _BLANK l = <-c if i, e := strconv.Atoi(l.token); e != nil { - if i, ok := StringToAlgorithm[strings.ToUpper(l.token)]; !ok { + if i, ok := StringToAlgorithm[l.tokenUpper]; !ok { return nil, &ParseError{f, "bad CDS Algorithm", l}, "" } else { rr.Algorithm = i @@ -1716,7 +1716,7 @@ func setDLV(h RR_Header, c chan lex, f string) (RR, *ParseError, string) { <-c // _BLANK l = <-c if i, e := strconv.Atoi(l.token); e != nil { - if i, ok := StringToAlgorithm[strings.ToUpper(l.token)]; !ok { + if i, ok := StringToAlgorithm[l.tokenUpper]; !ok { return nil, &ParseError{f, "bad DLV Algorithm", l}, "" } else { rr.Algorithm = i @@ -1751,7 +1751,7 @@ func setTA(h RR_Header, c chan lex, f string) (RR, *ParseError, string) { <-c // _BLANK l = <-c if i, e := strconv.Atoi(l.token); e != nil { - if i, ok := StringToAlgorithm[strings.ToUpper(l.token)]; !ok { + if i, ok := StringToAlgorithm[l.tokenUpper]; !ok { return nil, &ParseError{f, "bad TA Algorithm", l}, "" } else { rr.Algorithm = i