bug in _count_righthand_zero_bits

15 views
Skip to first unread message

BJ Premore

unread,
Sep 15, 2014, 11:20:28 AM9/15/14
to ipaddr...@googlegroups.com
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

unread,
Sep 15, 2014, 1:23:43 PM9/15/14
to BJ Premore, ipaddr...@googlegroups.com

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

unread,
Sep 15, 2014, 1:36:01 PM9/15/14
to Peter Moody, ipaddr...@googlegroups.com
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
Reply all
Reply to author
Forward
0 new messages