Parsing TXT records now works OK

This commit is contained in:
Miek Gieben 2012-02-12 22:24:18 +01:00
parent 6279bb1917
commit a7b2a88e7a
3 changed files with 65 additions and 57 deletions

View File

@ -206,8 +206,9 @@ func TestQuotes(t *testing.T) {
`t.example.com. IN TXT "abc" "DEF"`: "t.example.com.\t3600\tIN\tTXT\t\"abc\" \"DEF\"", `t.example.com. IN TXT "abc" "DEF"`: "t.example.com.\t3600\tIN\tTXT\t\"abc\" \"DEF\"",
`t.example.com. IN TXT "abc" ( "DEF" )`: "t.example.com.\t3600\tIN\tTXT\t\"abc\" \"DEF\"", `t.example.com. IN TXT "abc" ( "DEF" )`: "t.example.com.\t3600\tIN\tTXT\t\"abc\" \"DEF\"",
`t.example.com. IN TXT aaa ;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa \"", `t.example.com. IN TXT aaa ;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa \"",
`t.example.com. IN TXT aaa aaa;`: "t.example.com.\t3600\tIN\tTXT\t\"aaaaaa\"", `t.example.com. IN TXT aaa aaa;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa aaa\"",
// `t.example.com. IN TXT aaa`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\"", `t.example.com. IN TXT aaa aaa`: "t.example.com.\t3600\tIN\tTXT\t\"aaa aaa\"",
`t.example.com. IN TXT aaa`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\"",
// "cid.urn.arpa. NAPTR 100 50 \"s\" \"z3950+I2L+I2C\" \"\" _z3950._tcp.gatech.edu.": // "cid.urn.arpa. NAPTR 100 50 \"s\" \"z3950+I2L+I2C\" \"\" _z3950._tcp.gatech.edu.":
// "cid.urn.arpa.\t3600\tIN\tNAPTR\t100 50 \"s\" \"z3950+I2L+I2C\" \"\" _z3950._tcp.gatech.edu.", // "cid.urn.arpa.\t3600\tIN\tNAPTR\t100 50 \"s\" \"z3950+I2L+I2C\" \"\" _z3950._tcp.gatech.edu.",
// "cid.urn.arpa. NAPTR 100 50 \"s\" \"rcds+I2C\" \"\" _rcds._udp.gatech.edu.": // "cid.urn.arpa. NAPTR 100 50 \"s\" \"rcds+I2C\" \"\" _rcds._udp.gatech.edu.":

View File

@ -10,7 +10,7 @@ import (
) )
// Only used when debugging the parser itself. // Only used when debugging the parser itself.
var _DEBUG = true var _DEBUG = false
// Complete unsure about the correctness of this value? // Complete unsure about the correctness of this value?
// Large blobs of base64 code might get longer than this.... // Large blobs of base64 code might get longer than this....
@ -27,7 +27,7 @@ const (
_EOF = iota // Don't let it start with zero _EOF = iota // Don't let it start with zero
_STRING _STRING
_BLANK _BLANK
_QUOTE _QUOTE
_NEWLINE _NEWLINE
_RRTYPE _RRTYPE
_OWNER _OWNER
@ -237,9 +237,9 @@ func parseZone(r io.Reader, f string, t chan Token, include int) {
if !IsFqdn(l.token) { if !IsFqdn(l.token) {
origin = l.token + "." + origin // Append old origin if the new one isn't a fqdn origin = l.token + "." + origin // Append old origin if the new one isn't a fqdn
} else { } else {
origin = "." +l.token origin = "." + l.token
} }
st = _EXPECT_OWNER_DIR st = _EXPECT_OWNER_DIR
case _EXPECT_OWNER_BL: case _EXPECT_OWNER_BL:
if l.value != _BLANK { if l.value != _BLANK {
t <- Token{Error: &ParseError{f, "No blank after owner", l}} t <- Token{Error: &ParseError{f, "No blank after owner", l}}
@ -347,6 +347,8 @@ func (l lex) String() string {
return "S:" + l.token + "$" return "S:" + l.token + "$"
case _BLANK: case _BLANK:
return "_" return "_"
case _QUOTE:
return "\""
case _NEWLINE: case _NEWLINE:
return "|\n" return "|\n"
case _RRTYPE: case _RRTYPE:
@ -450,16 +452,22 @@ func zlexer(s scanner.Scanner, c chan lex) {
stri++ stri++
break break
} }
if stri > 0 {
l.value = _STRING
l.token = string(str[:stri])
c <- l
stri = 0
}
commt = true commt = true
case '\n': case '\n':
// Hmmm, escape newline // Hmmm, escape newline
if quote { if quote {
str[stri] = byte(x[0]) str[stri] = byte(x[0])
stri++ stri++
break break
} }
// inside quotes this is legal // inside quotes this is legal
escape = false escape = false
if commt { if commt {
// Reset a comment // Reset a comment
@ -506,7 +514,7 @@ func zlexer(s scanner.Scanner, c chan lex) {
rrtype = false rrtype = false
owner = true owner = true
case '\\': case '\\':
// quote? // quote?
if commt { if commt {
break break
} }
@ -530,22 +538,22 @@ func zlexer(s scanner.Scanner, c chan lex) {
break break
} }
// send previous gathered text and the quote // send previous gathered text and the quote
if stri != 0 { if stri != 0 {
l.value = _STRING l.value = _STRING
l.token = string(str[:stri]) l.token = string(str[:stri])
c <-l c <- l
stri = 0 stri = 0
} }
l.value = _QUOTE l.value = _QUOTE
l.token = "\"" l.token = "\""
c <- l c <- l
quote = !quote quote = !quote
case '(': case '(':
if quote { if quote {
str[stri] = byte(x[0]) str[stri] = byte(x[0])
stri++ stri++
break break
} }
if commt { if commt {
break break
} }
@ -557,11 +565,11 @@ func zlexer(s scanner.Scanner, c chan lex) {
} }
brace++ brace++
case ')': case ')':
if quote { if quote {
str[stri] = byte(x[0]) str[stri] = byte(x[0])
stri++ stri++
break break
} }
if commt { if commt {
break break
} }

View File

@ -709,37 +709,36 @@ func setTXT(h RR_Header, c chan lex, f string) (RR, *ParseError) {
// Get the remaining data until we see a NEWLINE // Get the remaining data until we see a NEWLINE
quote := false quote := false
quoted := false // unquoted strings are also allowed
l := <-c l := <-c
i := 0 var s []string
s := make([]string, i) switch l.value == _QUOTE {
if l.value == _QUOTE { case true: // A number of quoted string
quoted = true s = make([]string, 0)
} for l.value != _NEWLINE && l.value != _EOF {
for l.value != _NEWLINE && l.value != _EOF { switch l.value {
switch l.value { case _STRING:
case _STRING: s = append(s, l.token)
s = append(s, l.token) case _BLANK:
i++ if quote {
case _BLANK: // _BLANK can only be seen in between txt parts.
if !quoted { return nil, &ParseError{f, "bad TXT Txt", l}
if i = 0 { }
return nil, &ParseError{f, "bad TXT txt", l} case _QUOTE:
} quote = !quote
s[i-1] += l.token default:
l = <-c
continue
}
if quoted && quote {
// _BLANK can only be seen in between txt parts.
return nil, &ParseError{f, "bad TXT Txt", l} return nil, &ParseError{f, "bad TXT Txt", l}
} }
case _QUOTE: l = <-c
quote = !quote }
default: if quote {
return nil, &ParseError{f, "bad TXT Txt", l} return nil, &ParseError{f, "Bad TXT Txt", l}
}
case false: // Unquoted text record
s = make([]string, 1)
for l.value != _NEWLINE && l.value != _EOF {
s[0] += l.token
l = <-c
} }
l = <-c
} }
rr.Txt = s rr.Txt = s
return rr, nil return rr, nil