From 1006025d24f8fdd5b5ee8b3c15a714e6b24baaab Mon Sep 17 00:00:00 2001 From: Tim Cooper Date: Tue, 12 Dec 2023 19:26:53 -0600 Subject: [PATCH] fix IPv6Prefix bug --- attribute.go | 13 ++++++++----- attribute_test.go | 13 +++++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/attribute.go b/attribute.go index 473d230..366da72 100644 --- a/attribute.go +++ b/attribute.go @@ -467,18 +467,21 @@ func IPv6Prefix(a Attribute) (*net.IPNet, error) { } prefixLength := int(a[1]) - if (len(a)-2)*8 < prefixLength { + if prefixLength > net.IPv6len*8 { return nil, errors.New("invalid prefix length") } ip := make(net.IP, net.IPv6len) copy(ip, a[2:]) - // clear final non-mask bits - if i := uint(prefixLength % 8); i != 0 { - for ; i < 8; i++ { - ip[prefixLength/8] &^= 1 << (7 - i) + bit := uint(prefixLength % 8) + for octet := prefixLength / 8; octet < len(ip); octet++ { + for ; bit < 8; bit++ { + if ip[octet]&(1<<(7-bit)) != 0 { + return nil, errors.New("invalid prefix data") + } } + bit = 0 } return &net.IPNet{ diff --git a/attribute_test.go b/attribute_test.go index 9935b4e..20655d0 100644 --- a/attribute_test.go +++ b/attribute_test.go @@ -130,6 +130,19 @@ func TestIPv6Prefix(t *testing.T) { } } +func TestIPv6Prefix_issue118(t *testing.T) { + ipNet, err := IPv6Prefix([]byte{0x00, 0x40, 0x20, 0x01, 0x15, 0x30, 0x10, 0x0e}) + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + if expected := net.ParseIP("2001:1530:100e::"); !ipNet.IP.Equal(expected) { + t.Fatalf("got %v, expected %v", ipNet.IP, expected) + } + if ones, size := ipNet.Mask.Size(); ones != 64 || size != 128 { + t.Fatalf("got %v:%v, expected 64, 128", ones, size) + } +} + func ipNetEquals(a, b *net.IPNet) bool { if a == nil && b == nil { return true