]> Cypherpunks repositories - gostls13.git/commitdiff
net/netip: don't accept ParseAddr with leading zeros
authorBrad Fitzpatrick <bradfitz@golang.org>
Fri, 5 Nov 2021 04:35:55 +0000 (21:35 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Fri, 5 Nov 2021 16:54:01 +0000 (16:54 +0000)
Fixes #49365
Updates #30999

Change-Id: Ic92bce01b435baf70574c65524bde82f9cee3d8d
Reviewed-on: https://go-review.googlesource.com/c/go/+/361534
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Trust: Josh Bleecher Snyder <josharian@gmail.com>
Trust: Brad Fitzpatrick <bradfitz@golang.org>

src/net/netip/netip.go
src/net/netip/netip_test.go

index 02a4aa04525072b59fa2e0d95ce11c210f092b21..b0c13b81fc4881105e5efdfc51b8abfc56b631d3 100644 (file)
@@ -155,9 +155,14 @@ func (err parseAddrError) Error() string {
 func parseIPv4(s string) (ip Addr, err error) {
        var fields [4]uint8
        var val, pos int
+       var digLen int // number of digits in current octet
        for i := 0; i < len(s); i++ {
                if s[i] >= '0' && s[i] <= '9' {
+                       if digLen == 1 && val == 0 {
+                               return Addr{}, parseAddrError{in: s, msg: "IPv4 field has octet with leading zero"}
+                       }
                        val = val*10 + int(s[i]) - '0'
+                       digLen++
                        if val > 255 {
                                return Addr{}, parseAddrError{in: s, msg: "IPv4 field has value >255"}
                        }
@@ -175,6 +180,7 @@ func parseIPv4(s string) (ip Addr, err error) {
                        fields[pos] = uint8(val)
                        pos++
                        val = 0
+                       digLen = 0
                } else {
                        return Addr{}, parseAddrError{in: s, msg: "unexpected character", at: s[i:]}
                }
index 5d935c8fd37b7b555004f81801bcc1da02ff1228..241a71bb83c190ba6a00259907018d2864239f19 100644 (file)
@@ -29,9 +29,10 @@ var (
 
 func TestParseAddr(t *testing.T) {
        var validIPs = []struct {
-               in  string
-               ip  Addr   // output of ParseAddr()
-               str string // output of String(). If "", use in.
+               in      string
+               ip      Addr   // output of ParseAddr()
+               str     string // output of String(). If "", use in.
+               wantErr string
        }{
                // Basic zero IPv4 address.
                {
@@ -45,15 +46,18 @@ func TestParseAddr(t *testing.T) {
                },
                // IPv4 address in windows-style "print all the digits" form.
                {
-                       in:  "010.000.015.001",
-                       ip:  MkAddr(Mk128(0, 0xffff0a000f01), Z4),
-                       str: "10.0.15.1",
+                       in:      "010.000.015.001",
+                       wantErr: `ParseAddr("010.000.015.001"): IPv4 field has octet with leading zero`,
                },
                // IPv4 address with a silly amount of leading zeros.
                {
-                       in:  "000001.00000002.00000003.000000004",
-                       ip:  MkAddr(Mk128(0, 0xffff01020304), Z4),
-                       str: "1.2.3.4",
+                       in:      "000001.00000002.00000003.000000004",
+                       wantErr: `ParseAddr("000001.00000002.00000003.000000004"): IPv4 field has octet with leading zero`,
+               },
+               // 4-in-6 with octet with leading zero
+               {
+                       in:      "::ffff:1.2.03.4",
+                       wantErr: `ParseAddr("::ffff:1.2.03.4"): ParseAddr("1.2.03.4"): IPv4 field has octet with leading zero (at "1.2.03.4")`,
                },
                // Basic zero IPv6 address.
                {
@@ -121,10 +125,16 @@ func TestParseAddr(t *testing.T) {
                t.Run(test.in, func(t *testing.T) {
                        got, err := ParseAddr(test.in)
                        if err != nil {
+                               if err.Error() == test.wantErr {
+                                       return
+                               }
                                t.Fatal(err)
                        }
+                       if test.wantErr != "" {
+                               t.Fatalf("wanted error %q; got none", test.wantErr)
+                       }
                        if got != test.ip {
-                               t.Errorf("ParseAddr(%q) got %#v, want %#v", test.in, got, test.ip)
+                               t.Errorf("got %#v, want %#v", got, test.ip)
                        }
 
                        // Check that ParseAddr is a pure function.
@@ -963,7 +973,7 @@ func TestIs4In6(t *testing.T) {
                {mustIP("::ffff:192.0.2.128"), true, mustIP("192.0.2.128")},
                {mustIP("::ffff:192.0.2.128%eth0"), true, mustIP("192.0.2.128")},
                {mustIP("::fffe:c000:0280"), false, mustIP("::fffe:c000:0280")},
-               {mustIP("::ffff:127.001.002.003"), true, mustIP("127.1.2.3")},
+               {mustIP("::ffff:127.1.2.3"), true, mustIP("127.1.2.3")},
                {mustIP("::ffff:7f01:0203"), true, mustIP("127.1.2.3")},
                {mustIP("0:0:0:0:0000:ffff:127.1.2.3"), true, mustIP("127.1.2.3")},
                {mustIP("0:0:0:0:000000:ffff:127.1.2.3"), true, mustIP("127.1.2.3")},