From 9c6e8f63c0e4f24ccf4326164ddbc0f0607343a2 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Sat, 11 Dec 2021 19:35:08 -0800 Subject: [PATCH] net/netip: make AddrPort.MarshalText format 4-in-6 IPs consistently Thanks again to @capnspacehook. Fixes #50110 Change-Id: I1973bdea68eac9842b45f9524f62152e4f5342cf Reviewed-on: https://go-review.googlesource.com/c/go/+/371114 Run-TryBot: Brad Fitzpatrick Reviewed-by: Matt Layher Trust: Matt Layher Trust: Brad Fitzpatrick TryBot-Result: Gopher Robot --- src/net/netip/netip.go | 13 +++++++++++-- src/net/netip/netip_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/net/netip/netip.go b/src/net/netip/netip.go index dc5faff40f..aaaf435ed8 100644 --- a/src/net/netip/netip.go +++ b/src/net/netip/netip.go @@ -1157,8 +1157,17 @@ func (p AddrPort) AppendTo(b []byte) []byte { case z4: b = p.ip.appendTo4(b) default: - b = append(b, '[') - b = p.ip.appendTo6(b) + if p.ip.Is4In6() { + b = append(b, "[::ffff:"...) + b = p.ip.Unmap().appendTo4(b) + if z := p.ip.Zone(); z != "" { + b = append(b, '%') + b = append(b, z...) + } + } else { + b = append(b, '[') + b = p.ip.appendTo6(b) + } b = append(b, ']') } b = append(b, ':') diff --git a/src/net/netip/netip_test.go b/src/net/netip/netip_test.go index 2105545139..869628050a 100644 --- a/src/net/netip/netip_test.go +++ b/src/net/netip/netip_test.go @@ -347,6 +347,32 @@ func TestAddrMarshalUnmarshalBinary(t *testing.T) { } } +func TestAddrPortMarshalTextString(t *testing.T) { + tests := []struct { + in AddrPort + want string + }{ + {mustIPPort("1.2.3.4:80"), "1.2.3.4:80"}, + {mustIPPort("[1::CAFE]:80"), "[1::cafe]:80"}, + {mustIPPort("[1::CAFE%en0]:80"), "[1::cafe%en0]:80"}, + {mustIPPort("[::FFFF:192.168.140.255]:80"), "[::ffff:192.168.140.255]:80"}, + {mustIPPort("[::FFFF:192.168.140.255%en0]:80"), "[::ffff:192.168.140.255%en0]:80"}, + } + for i, tt := range tests { + if got := tt.in.String(); got != tt.want { + t.Errorf("%d. for (%v, %v) String = %q; want %q", i, tt.in.Addr(), tt.in.Port(), got, tt.want) + } + mt, err := tt.in.MarshalText() + if err != nil { + t.Errorf("%d. for (%v, %v) MarshalText error: %v", i, tt.in.Addr(), tt.in.Port(), err) + continue + } + if string(mt) != tt.want { + t.Errorf("%d. for (%v, %v) MarshalText = %q; want %q", i, tt.in.Addr(), tt.in.Port(), mt, tt.want) + } + } +} + func TestAddrPortMarshalUnmarshalBinary(t *testing.T) { tests := []struct { ipport string -- 2.50.0