Skip to content

Commit

Permalink
pkg/ipnet: fix Unmarshal to match ParseCIDR output
Browse files Browse the repository at this point in the history
Before this change
```
net.ParseCIDR("192.168.0.10/24") returns "192.168.0.0/24" as network.
while json.Unmarshal(`"192.168.0.10/24"`) returns "192.168.0.10/24" as network.
```

This fixes the json.Unmarshal to `pkg/ipnet/IPNet` to match `net.ParseCIDR`
  • Loading branch information
abhinavdahiya committed Jan 15, 2019
1 parent 5f357d2 commit 28494bb
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 24 deletions.
8 changes: 4 additions & 4 deletions pkg/ipnet/ipnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (ipnet *IPNet) UnmarshalJSON(b []byte) (err error) {
return errors.Wrap(err, "failed to Unmarshal string")
}

ip, net, err := net.ParseCIDR(cidr)
_, net, err := net.ParseCIDR(cidr)
if err != nil {
return errors.Wrap(err, "failed to Parse cidr string to net.IPNet")
}
Expand All @@ -61,10 +61,10 @@ func (ipnet *IPNet) UnmarshalJSON(b []byte) (err error) {
// which is what some libraries (e.g. github.com/apparentlymart/go-cidr)
// assume. By forcing the address to be the expected length, we can work
// around these bugs.
if ip.To4() != nil {
ipnet.IP = ip.To4()
if net.IP.To4() != nil {
ipnet.IP = net.IP.To4()
} else {
ipnet.IP = ip
ipnet.IP = net.IP
}
ipnet.Mask = net.Mask

Expand Down
54 changes: 34 additions & 20 deletions pkg/ipnet/ipnet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"encoding/json"
"net"
"testing"

"github.com/stretchr/testify/assert"
)

func assertJSON(t *testing.T, data interface{}, expected string) {
Expand Down Expand Up @@ -31,27 +33,39 @@ func TestMarshal(t *testing.T) {
}

func TestUnmarshal(t *testing.T) {
for _, ipNetIn := range []*IPNet{
nil,
{IPNet: net.IPNet{
IP: net.IP{192, 168, 0, 10},
Mask: net.IPv4Mask(255, 255, 255, 0),
}},
} {
t.Run(ipNetIn.String(), func(t *testing.T) {
data, err := json.Marshal(ipNetIn)
if err != nil {
t.Fatal(err)
}

var ipNetOut *IPNet
err = json.Unmarshal(data, &ipNetOut)
if err != nil {
t.Fatal(err)
}
tests := []struct {
input string

if ipNetOut.String() != ipNetIn.String() {
t.Fatalf("%v != %v", ipNetOut, ipNetIn)
exp *IPNet
expErr string
}{{
input: `""`,
expErr: "failed to Parse cidr string to net.IPNet: invalid CIDR address: ",
}, {
input: ``,
expErr: "unexpected end of JSON input",
}, {
input: `null`,
exp: &IPNet{net.IPNet{IP: net.IP{}, Mask: net.IPMask{}}},
}, {
input: `"null"`,
expErr: "failed to Parse cidr string to net.IPNet: invalid CIDR address: null",
}, {
input: `"192.168.0.10/24"`,
exp: &IPNet{net.IPNet{IP: net.IP{0xc0, 0xa8, 0x0, 0x0}, Mask: net.IPMask{0xff, 0xff, 0xff, 0x0}}},
}, {
input: `"fe80::c0a8:a/120"`,
exp: &IPNet{net.IPNet{IP: net.IP{0xfe, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0xa8, 0x0, 0x0}, Mask: net.IPMask{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0}}},
}}
for _, test := range tests {
t.Run(test.input, func(t *testing.T) {
var ipNetOut IPNet
err := json.Unmarshal([]byte(test.input), &ipNetOut)
if test.expErr == "" {
assert.NoError(t, err)
assert.Equal(t, test.exp, &ipNetOut)
} else {
assert.EqualError(t, err, test.expErr)
}
})
}
Expand Down

0 comments on commit 28494bb

Please sign in to comment.