Conversation
|
This kinda sounds like a bug I encountered a few months back, that was triggered, when the following set of conditions were met:
Due to some API inconsistency, the return value was |
That's the behavior I noticed in a Rust port I'm writing fix ref. But I wasn't totally convinced there was no loop in the C implementation here. |
|
Thanks. I'll make sure this is fixed in the next release. |
|
I also encountered this during some fuzzing on a Rust port. My st_step_search impl looks like this now fn st_step_search(&mut self) -> HSEState {
let window_length = self.input_buffer_size;
let lookahead_sz = self.lookahead_size;
let msi = self.match_scan_index;
if msi > self.input_size.saturating_sub(lookahead_sz) {
return HSEState::SaveBacklog;
} else if unlikely(self.is_finishing()) && msi >= self.input_size {
return HSEState::FlushBits;
}
let input_offset = self.get_input_offset();
let end = input_offset + msi;
let start = end - window_length;
... |
Via some fuzzing, I found a finish scenario that can result in incorrect encoding. This PR addresses the bug by adding a check for
finishing && input size == 0in the search step to transition to flush bits.Explanation:
At finish time, if the
input_sizeis 0 then there is no more data to encode and the remaining bits should be flushed. However, because the search step doesinput_size - 1this results in an overflow and the search step transitions to yielding a tag bit instead. I'm not really sure what happens from this point on, but I suspect it may loop infinitely.