tomerfiliba-org / reedsolomon

⏳🛡 Pythonic universal errors-and-erasures Reed-Solomon codec to protect your data from errors and bitrot. Includes a future-proof zero-dependencies pure-python implementation 🔮 and an optional speed-optimized Cython/C extension 🚀
http://pypi.python.org/pypi/reedsolo
Other
351 stars 86 forks source link

Code does not work when decoding chunked messages when erase_pos is used #47

Closed another-pjohnson closed 1 year ago

another-pjohnson commented 2 years ago

Example failure

import reedsolo
rsc = reedsolo.RSCodec(30)
encoded = rsc.encode(b'0' * 226)
_, _, _ = rsc.decode(encoded, erase_pos=[255], only_erasures=True)

output:

Traceback (most recent call last):
  File "demo.py", line 4, in <module>
    _, _, _ = rsc.decode(encoded, erase_pos=[255], only_erasures=True)
  File "reedsolo.py", line 927, in decode
    rmes, recc, errata_pos = rs_correct_msg(chunk, nsym, fcr=self.fcr, generator=self.generator, erase_pos=e_pos, only_erasures=only_erasures)
  File "reedsolo.py", line 731, in rs_correct_msg
    msg_out[e_pos] = 0
IndexError: bytearray index out of range

Erasure position calculation for the 2nd chunk onward are incorrect due to this line:

922                 e_pos = [x for x in erase_pos if x <= self.nsize]
923                 ...
924                 erase_pos = [x - (self.nsize+1) for x in erase_pos if x > self.nsize]

it should be:

922                 e_pos = [x for x in erase_pos if x < self.nsize]
923                 ...
924                 erase_pos = [x - (self.nsize) for x in erase_pos if x >= self.nsize]
lrq3000 commented 1 year ago

Merged, thank you very much, next time you can create a PR so that I can credit you directly, but I mentioned you in the commit message anyway. Thank you very much again for catching this very hard to spot miscalculation, have a great day!