cunla / fakeredis-py

Implementation of Redis in python without having a Redis server running. Fully compatible with using redis-py.
https://fakeredis.moransoftware.ca/
BSD 3-Clause "New" or "Revised" License
299 stars 49 forks source link

fix:bug in bitpos function for the clear bit mode #337

Closed Diskein closed 1 month ago

Diskein commented 1 month ago

Hey! Thanks for the library! :rocket:

I've recently been testing dragonfly's BITPOS implementation with fakeredis and stumbled upon some bugs in fakeredis's implementation, so I've decided to fix it. The misbehaving is related to the clear bit mode i.e. when BITPOS command looking for 0 bit.

https://redis.io/docs/latest/commands/bitpos/

If we look for clear bits (the bit argument is 0) and the string only contains bits set to 1, the function returns the first bit not part of the string on the right. So if the string is three bytes set to the value 0xff the command BITPOS key 0 will return 24, since up to bit 23 all the bits are 1.

The function considers the right of the string as padded with zeros if you look for clear bits and specify no range or the start argument only.

However, this behavior changes if you are looking for clear bits and specify a range with both start and end. If a clear bit isn't found in the specified range, the function returns -1 as the user specified a clear range and there are no 0 bits in that range.

This PR fixes this, so for the clear bit mode:

cunla commented 1 month ago

Hi, thank you for the fix. Please run flake8 and black on the code. Also, it is not clear to me why you created positive_range instead of fixing fix_range?

cunla commented 1 month ago

Hi, I simplified the changes a bit. Thanks again for your contribution!