# bug in _count_righthand_zero_bits

15 views

### BJ Premore

Sep 15, 2014, 11:20:28 AM9/15/14
Hello,

Just joined here to report a bug in _count_righthand_zero_bits(number, bits).

For quick reference, here is the function
`def _count_righthand_zero_bits(number, bits):`
"""Count the number of zero bits on the right hand side.

Args:
number: an integer.
bits: maximum number of bits to count.

Returns:
The number of zero bits on the right hand side of the number.

"""
if number == 0:
return bits
for i in range(bits):
if (number >> i) % 2:
return i

In the case where all 'bits' bits are zeroes, control falls out of the for loop and no result is returned.

For example, calling _count_righthand_zero_bits(8,2) should return 2.

The simple solution here is to add 'return bits' after the for loop:
`    if number == 0:        return bits    for i in range(bits):        if (number >> i) % 2:            return i    return bits`

BJ

### Peter Moody

Sep 15, 2014, 1:23:43 PM9/15/14

Hey BJ, thanks for this report.

It's been a while since I've looked at this code; can you give me an
example of an address range that'll result in _count_righthand_zero_bits
being called like that?

### BJ Premore

Sep 15, 2014, 1:36:01 PM9/15/14
Hi Peter. Looks like _count_righthand_zero_bits is only called from
one place in the module, and from that context, it may not ever tickle
that bug, I'm not sure. I was actually calling it directly from my own
code in which I wanted to check whether a prefix had any extra bits
set (beyond the prefix length). For example:

129.170.0.0/16 is well-formed in that all bits after the first 16 are zeroes.
129.170.1.0/16 does have a bit set beyond the prefix length

A lot of prefix parsers (ipaddr.py code included) tolerate extra bits
set in this fashion. However, I needed to catch prefixes with extra
bits set, so I was taking the integer form of a prefix and checking
whether the number of righthand zero bits was less than or equal to 32
minus the prefix length.

For example, for IPAddress object p, this code performs that check:

if (_count_righthand_zero_bits(p._ip, p._max_prefixlen-p._prefixlen) <
(p._max_prefixlen-p._prefixlen)):
# do something

Hope that helps clarify,

BJ