From a7b2a88e7adb5fb0a0efc97db262657b8c6d5962 Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Sun, 12 Feb 2012 22:24:18 +0100 Subject: [PATCH] Parsing TXT records now works OK --- parse_test.go | 5 ++-- zscan.go | 64 +++++++++++++++++++++++++++++---------------------- zscan_rr.go | 53 +++++++++++++++++++++--------------------- 3 files changed, 65 insertions(+), 57 deletions(-) diff --git a/parse_test.go b/parse_test.go index 795356ae..c7382622 100644 --- a/parse_test.go +++ b/parse_test.go @@ -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 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`: "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 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.\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.": diff --git a/zscan.go b/zscan.go index 9ca6de0c..1fcbc8a9 100644 --- a/zscan.go +++ b/zscan.go @@ -10,7 +10,7 @@ import ( ) // Only used when debugging the parser itself. -var _DEBUG = true +var _DEBUG = false // Complete unsure about the correctness of this value? // Large blobs of base64 code might get longer than this.... @@ -27,7 +27,7 @@ const ( _EOF = iota // Don't let it start with zero _STRING _BLANK - _QUOTE + _QUOTE _NEWLINE _RRTYPE _OWNER @@ -237,9 +237,9 @@ func parseZone(r io.Reader, f string, t chan Token, include int) { if !IsFqdn(l.token) { origin = l.token + "." + origin // Append old origin if the new one isn't a fqdn } else { - origin = "." +l.token + origin = "." + l.token } - st = _EXPECT_OWNER_DIR + st = _EXPECT_OWNER_DIR case _EXPECT_OWNER_BL: if l.value != _BLANK { t <- Token{Error: &ParseError{f, "No blank after owner", l}} @@ -347,6 +347,8 @@ func (l lex) String() string { return "S:" + l.token + "$" case _BLANK: return "_" + case _QUOTE: + return "\"" case _NEWLINE: return "|\n" case _RRTYPE: @@ -450,16 +452,22 @@ func zlexer(s scanner.Scanner, c chan lex) { stri++ break } + if stri > 0 { + l.value = _STRING + l.token = string(str[:stri]) + c <- l + stri = 0 + } commt = true case '\n': // Hmmm, escape newline - if quote { + if quote { str[stri] = byte(x[0]) - stri++ - break - } + stri++ + break + } - // inside quotes this is legal + // inside quotes this is legal escape = false if commt { // Reset a comment @@ -506,7 +514,7 @@ func zlexer(s scanner.Scanner, c chan lex) { rrtype = false owner = true case '\\': - // quote? + // quote? if commt { break } @@ -530,22 +538,22 @@ func zlexer(s scanner.Scanner, c chan lex) { break } // send previous gathered text and the quote - if stri != 0 { - l.value = _STRING - l.token = string(str[:stri]) - c <-l - stri = 0 - } - l.value = _QUOTE - l.token = "\"" - c <- l + if stri != 0 { + l.value = _STRING + l.token = string(str[:stri]) + c <- l + stri = 0 + } + l.value = _QUOTE + l.token = "\"" + c <- l quote = !quote case '(': - if quote { + if quote { str[stri] = byte(x[0]) - stri++ - break - } + stri++ + break + } if commt { break } @@ -557,11 +565,11 @@ func zlexer(s scanner.Scanner, c chan lex) { } brace++ case ')': - if quote { - str[stri] = byte(x[0]) - stri++ - break - } + if quote { + str[stri] = byte(x[0]) + stri++ + break + } if commt { break } diff --git a/zscan_rr.go b/zscan_rr.go index 32e45e49..7795ace9 100644 --- a/zscan_rr.go +++ b/zscan_rr.go @@ -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 quote := false - quoted := false // unquoted strings are also allowed l := <-c - i := 0 - s := make([]string, i) - if l.value == _QUOTE { - quoted = true - } - for l.value != _NEWLINE && l.value != _EOF { - switch l.value { - case _STRING: - s = append(s, l.token) - i++ - case _BLANK: - if !quoted { - if i = 0 { - return nil, &ParseError{f, "bad TXT txt", l} - } - s[i-1] += l.token - l = <-c - continue - } - if quoted && quote { - // _BLANK can only be seen in between txt parts. + var s []string + switch l.value == _QUOTE { + case true: // A number of quoted string + s = make([]string, 0) + for l.value != _NEWLINE && l.value != _EOF { + switch l.value { + case _STRING: + s = append(s, l.token) + case _BLANK: + if quote { + // _BLANK can only be seen in between txt parts. + return nil, &ParseError{f, "bad TXT Txt", l} + } + case _QUOTE: + quote = !quote + default: return nil, &ParseError{f, "bad TXT Txt", l} } - case _QUOTE: - quote = !quote - default: - return nil, &ParseError{f, "bad TXT Txt", l} + l = <-c + } + if quote { + 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 return rr, nil