From e27c5f9b6bbdf3e1181c902e9b06f9d7acc18405 Mon Sep 17 00:00:00 2001 From: Yulin Chen Date: Mon, 11 Sep 2017 16:22:01 -0700 Subject: [PATCH] Fix index-out-of-bound bug when inserting network that shares direct branch point with single-IP (leaf) network, closes #3 --- trie.go | 10 ++++++---- trie_test.go | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/trie.go b/trie.go index 6073900..16792d4 100644 --- a/trie.go +++ b/trie.go @@ -188,7 +188,7 @@ func (p *prefixTrie) insert(network rnet.Network, entry RangerEntry) error { if err != nil { return err } - if lcb-1 > child.targetBitPosition() { + if int(lcb) > child.targetBitPosition()+1 { child = newPathprefixTrie(network, p.totalNumberOfBits()-lcb) err := p.insertPrefix(bit, child) if err != nil { @@ -259,12 +259,14 @@ func (p *prefixTrie) totalNumberOfBits() uint { return rnet.BitsPerUint32 * uint(len(p.network.Number)) } -func (p *prefixTrie) targetBitPosition() uint { - return p.totalNumberOfBits() - p.numBitsSkipped - 1 +func (p *prefixTrie) targetBitPosition() int { + return int(p.totalNumberOfBits()-p.numBitsSkipped) - 1 } func (p *prefixTrie) targetBitFromIP(n rnet.NetworkNumber) (uint32, error) { - return n.Bit(p.targetBitPosition()) + // This is a safe uint boxing of int since we should never attempt to get + // target bit at a negative position. + return n.Bit(uint(p.targetBitPosition())) } func (p *prefixTrie) hasEntry() bool { diff --git a/trie_test.go b/trie_test.go index 8eb6483..6794da1 100644 --- a/trie_test.go +++ b/trie_test.go @@ -16,12 +16,30 @@ func TestPrefixTrieInsert(t *testing.T) { name string }{ {rnet.IPv4, []string{"192.168.0.1/24"}, []string{"192.168.0.1/24"}, "basic insert"}, + { + rnet.IPv4, + []string{"1.2.3.4/32", "1.2.3.5/32"}, + []string{"1.2.3.4/32", "1.2.3.5/32"}, + "single ip IPv4 network insert", + }, + { + rnet.IPv6, + []string{"0::1/128", "0::2/128"}, + []string{"0::1/128", "0::2/128"}, + "single ip IPv6 network insert", + }, { rnet.IPv4, []string{"192.168.0.1/16", "192.168.0.1/24"}, []string{"192.168.0.1/16", "192.168.0.1/24"}, "in order insert", }, + { + rnet.IPv4, + []string{"192.168.0.1/32", "192.168.0.1/32"}, + []string{"192.168.0.1/32"}, + "duplicate network insert", + }, { rnet.IPv4, []string{"192.168.0.1/24", "192.168.0.1/16"}, @@ -97,6 +115,22 @@ func TestPrefixTrieRemove(t *testing.T) { []string{}, "basic remove", }, + { + rnet.IPv4, + []string{"1.2.3.4/32", "1.2.3.5/32"}, + []string{"1.2.3.5/32"}, + []string{"1.2.3.5/32"}, + []string{"1.2.3.4/32"}, + "single ip IPv4 network remove", + }, + { + rnet.IPv4, + []string{"0::1/128", "0::2/128"}, + []string{"0::2/128"}, + []string{"0::2/128"}, + []string{"0::1/128"}, + "single ip IPv6 network remove", + }, { rnet.IPv4, []string{"192.168.0.1/24", "192.168.0.1/25", "192.168.0.1/26"}, -- GitLab