From 307f8b5a6d21ff6b00f1a09589e1e366450c7509 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Mon, 24 Sep 2018 06:08:54 -0400 Subject: [PATCH] [release-branch.go1.11] net: concatenate multiple TXT strings in single TXT record When go resolver was changed to use dnsmessage.Parser, LookupTXT returned two strings in one record as two different records. This change reverts back to concatenating multiple strings in a single TXT record. Updates #27763 Fixes #27886 Change-Id: Ice226fcb2be4be58853de34ed35b4627acb429ea Reviewed-on: https://go-review.googlesource.com/136955 Reviewed-by: Ian Gudger Reviewed-by: Brad Fitzpatrick Run-TryBot: Ian Gudger TryBot-Result: Gobot Gobot (cherry picked from commit 7b3b160323b56b357832549fbab7a60d27688ec1) Reviewed-on: https://go-review.googlesource.com/138177 Run-TryBot: Brad Fitzpatrick Reviewed-by: Katie Hockman --- src/net/dnsclient_unix_test.go | 53 ++++++++++++++++++++++++++++++++++ src/net/lookup_unix.go | 16 ++++++++-- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/src/net/dnsclient_unix_test.go b/src/net/dnsclient_unix_test.go index 9e4ebcc7bbef8..9482fc466f443 100644 --- a/src/net/dnsclient_unix_test.go +++ b/src/net/dnsclient_unix_test.go @@ -1568,3 +1568,56 @@ func TestDNSDialTCP(t *testing.T) { t.Fatal("exhange failed:", err) } } + +// Issue 27763: verify that two strings in one TXT record are concatenated. +func TestTXTRecordTwoStrings(t *testing.T) { + fake := fakeDNSServer{ + rh: func(n, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) { + r := dnsmessage.Message{ + Header: dnsmessage.Header{ + ID: q.Header.ID, + Response: true, + RCode: dnsmessage.RCodeSuccess, + }, + Questions: q.Questions, + Answers: []dnsmessage.Resource{ + { + Header: dnsmessage.ResourceHeader{ + Name: q.Questions[0].Name, + Type: dnsmessage.TypeA, + Class: dnsmessage.ClassINET, + }, + Body: &dnsmessage.TXTResource{ + TXT: []string{"string1 ", "string2"}, + }, + }, + { + Header: dnsmessage.ResourceHeader{ + Name: q.Questions[0].Name, + Type: dnsmessage.TypeA, + Class: dnsmessage.ClassINET, + }, + Body: &dnsmessage.TXTResource{ + TXT: []string{"onestring"}, + }, + }, + }, + } + return r, nil + }, + } + r := Resolver{PreferGo: true, Dial: fake.DialContext} + txt, err := r.lookupTXT(context.Background(), "golang.org") + if err != nil { + t.Fatal("LookupTXT failed:", err) + } + if want := 2; len(txt) != want { + t.Fatalf("len(txt), got %d, want %d", len(txt), want) + } + if want := "string1 string2"; txt[0] != want { + t.Errorf("txt[0], got %q, want %q", txt[0], want) + } + if want := "onestring"; txt[1] != want { + t.Errorf("txt[1], got %q, want %q", txt[1], want) + } +} diff --git a/src/net/lookup_unix.go b/src/net/lookup_unix.go index 2c3191aca8a66..f55ef5969eb16 100644 --- a/src/net/lookup_unix.go +++ b/src/net/lookup_unix.go @@ -299,11 +299,21 @@ func (r *Resolver) lookupTXT(ctx context.Context, name string) ([]string, error) Server: server, } } + // Multiple strings in one TXT record need to be + // concatenated without separator to be consistent + // with previous Go resolver. + n := 0 + for _, s := range txt.TXT { + n += len(s) + } + txtJoin := make([]byte, 0, n) + for _, s := range txt.TXT { + txtJoin = append(txtJoin, s...) + } if len(txts) == 0 { - txts = txt.TXT - } else { - txts = append(txts, txt.TXT...) + txts = make([]string, 0, 1) } + txts = append(txts, string(txtJoin)) } return txts, nil }