From a8990ae1e1e5811ffe1ee12ee90095b69e7f9991 Mon Sep 17 00:00:00 2001 From: Tom Limoncelli Date: Fri, 27 Dec 2024 14:02:29 -0500 Subject: [PATCH] NAMEDOTCOM: BUGFIX: TXT records add unneeded quotes (#3260) --- providers/namedotcom/auditrecords.go | 10 +++---- providers/namedotcom/records.go | 25 ++-------------- providers/namedotcom/records_test.go | 43 ---------------------------- 3 files changed, 7 insertions(+), 71 deletions(-) delete mode 100644 providers/namedotcom/records_test.go diff --git a/providers/namedotcom/auditrecords.go b/providers/namedotcom/auditrecords.go index 8e7d0f329d..94d8442d25 100644 --- a/providers/namedotcom/auditrecords.go +++ b/providers/namedotcom/auditrecords.go @@ -18,13 +18,13 @@ func AuditRecords(records []*models.RecordConfig) []error { a.Add("SRV", rejectif.SrvHasNullTarget) // Last verified 2020-12-28 - a.Add("TXT", MaxLengthNDC) // Last verified 2021-03-01 + a.Add("TXT", MaxLengthNDC) // Last verified 2024-12-17 - a.Add("TXT", rejectif.TxtIsEmpty) // Last verified 2023-11-18 + a.Add("TXT", rejectif.TxtHasDoubleQuotes) // Last verified 2024-12-17 - a.Add("TXT", rejectif.TxtHasBackslash) // Last verified 2023-11-18 - // Backslashes may be allowed in the API but the current - // encodeTxt/decodeTxt functions don't support backslashes. + a.Add("TXT", rejectif.TxtHasTrailingSpace) // Last verified 2024-12-17 + + a.Add("TXT", rejectif.TxtIsEmpty) // Last verified 2024-12-17 return a.Audit(records) } diff --git a/providers/namedotcom/records.go b/providers/namedotcom/records.go index b457ba3793..944f68d272 100644 --- a/providers/namedotcom/records.go +++ b/providers/namedotcom/records.go @@ -3,12 +3,10 @@ package namedotcom import ( "errors" "fmt" - "regexp" "strings" "github.com/StackExchange/dnscontrol/v4/models" "github.com/StackExchange/dnscontrol/v4/pkg/diff" - "github.com/StackExchange/dnscontrol/v4/pkg/txtutil" "github.com/namedotcom/go/namecom" ) @@ -95,7 +93,7 @@ func toRecord(r *namecom.Record, origin string) *models.RecordConfig { rc.SetLabelFromFQDN(fqdn, origin) switch rtype := r.Type; rtype { // #rtype_variations case "TXT": - rc.SetTargetTXTs(decodeTxt(r.Answer)) + rc.SetTargetTXT(r.Answer) case "MX": if err := rc.SetTargetMX(uint16(r.Priority), r.Answer); err != nil { panic(fmt.Errorf("unparsable MX record received from ndc: %w", err)) @@ -155,7 +153,7 @@ func (n *namedotcomProvider) createRecord(rc *models.RecordConfig, domain string case "A", "AAAA", "ANAME", "CNAME", "MX", "NS": // nothing case "TXT": - record.Answer = txtutil.EncodeQuoted(rc.GetTargetTXTJoined()) + record.Answer = rc.GetTargetTXTJoined() case "SRV": if rc.GetTargetField() == "." { return errors.New("SRV records with empty targets are not supported (as of 2019-11-05, the API returns 'Parameter Value Error - Invalid Srv Format')") @@ -171,25 +169,6 @@ func (n *namedotcomProvider) createRecord(rc *models.RecordConfig, domain string return err } -// finds a string surrounded by quotes that might contain an escaped quote character. -var quotedStringRegexp = regexp.MustCompile(`"((?:[^"\\]|\\.)*)"`) - -// decodeTxt decodes the TXT record as received from name.com and -// returns the list of strings. -// NB(tlim): This is very similar to txtutil.ParseQuoted. Maybe replace it some day? -func decodeTxt(s string) []string { - - if len(s) >= 2 && s[0] == '"' && s[len(s)-1] == '"' { - txtStrings := []string{} - for _, t := range quotedStringRegexp.FindAllStringSubmatch(s, -1) { - txtString := strings.Replace(t[1], `\"`, `"`, -1) - txtStrings = append(txtStrings, txtString) - } - return txtStrings - } - return []string{s} -} - func (n *namedotcomProvider) deleteRecord(id int32, domain string) error { request := &namecom.DeleteRecordRequest{ DomainName: domain, diff --git a/providers/namedotcom/records_test.go b/providers/namedotcom/records_test.go deleted file mode 100644 index 033d1f5435..0000000000 --- a/providers/namedotcom/records_test.go +++ /dev/null @@ -1,43 +0,0 @@ -package namedotcom - -import ( - "strings" - "testing" -) - -var txtData = []struct { - decoded []string - encoded string -}{ - {[]string{`simple`}, `simple`}, - {[]string{`changed`}, `changed`}, - {[]string{`with spaces`}, `with spaces`}, - {[]string{`with whitespace`}, `with whitespace`}, - {[]string{"one", "two"}, `"one""two"`}, - {[]string{"eh", "bee", "cee"}, `"eh""bee""cee"`}, - {[]string{"o\"ne", "tw\"o"}, `"o\"ne""tw\"o"`}, - {[]string{"dimple"}, `dimple`}, - //{[]string{`back\slash`}, `"back\\slash"`}, // Not yet supported - //{[]string{`back\\slash`}, `"back\\\\slash"`}, // Not yet supported - //{[]string{`back\\\slash`}, `"back\\\\\\slash"`}, // Not yet supported - {[]string{"fun", "two"}, `"fun""two"`}, - {[]string{"eh", "bzz", "cee"}, `"eh""bzz""cee"`}, -} - -func TestDecodeTxt(t *testing.T) { - // Test decoded a string into the list of strings: - for i, test := range txtData { - data := test.encoded - got := decodeTxt(data) - wanted := test.decoded - if len(got) != len(wanted) { - t.Errorf("%v: txt\n decode: %v\nexpected: `%v`\n got: `%v`\n", i, data, strings.Join(wanted, "`, `"), strings.Join(got, "`, `")) - } else { - for j := range got { - if got[j] != wanted[j] { - t.Errorf("%v: txt\n decode: %v\nexpected: `%v`\n got: `%v`\n", i, data, strings.Join(wanted, "`, `"), strings.Join(got, "`, `")) - } - } - } - } -}