diff --git a/trie.go b/trie.go index 6073900b0b506001e33ce9644e962626325b4d58..16792d4aab8d03f4558a34bf77c4d6c358cbcc79 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 8eb6483ec06a784e22221ccb2b8eade333bdb11b..6794da1d016bca64ed75d68e2033b0f3a55c0a47 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"},