Skip to content

Commit a82a5c9

Browse files
committed
Fix BzDecoder to propagate UnexpectedEof error on truncated streams
Fixes #411 The async BzDecoder was silently accepting truncated bzip2 streams, returning Ok(0) instead of raising an error. This contrasts with the synchronous bzip2::read::BzDecoder which properly returns an UnexpectedEof error. Added state tracking to BzDecoder: - Added stream_ended field to track if Status::StreamEnd was received - Modified decode() to set stream_ended = true on Status::StreamEnd - Updated finish() to check stream_ended and return UnexpectedEof if false This ensures applications cannot accidentally accept corrupted or incomplete compressed data as valid, matching the behavior of the synchronous decoder. The generic truncated test now passes for bzip2.
1 parent 71d1d68 commit a82a5c9

File tree

1 file changed

+16
-1
lines changed

1 file changed

+16
-1
lines changed

crates/compression-codecs/src/bzip2/decoder.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::{fmt, io};
55

66
pub struct BzDecoder {
77
decompress: Decompress,
8+
stream_ended: bool,
89
}
910

1011
impl fmt::Debug for BzDecoder {
@@ -22,6 +23,7 @@ impl Default for BzDecoder {
2223
fn default() -> Self {
2324
Self {
2425
decompress: Decompress::new(false),
26+
stream_ended: false,
2527
}
2628
}
2729
}
@@ -49,13 +51,19 @@ impl BzDecoder {
4951
input.advance((self.decompress.total_in() - prior_in) as usize);
5052
output.advance((self.decompress.total_out() - prior_out) as usize);
5153

54+
// Track when stream has properly ended
55+
if status == Status::StreamEnd {
56+
self.stream_ended = true;
57+
}
58+
5259
Ok(status)
5360
}
5461
}
5562

5663
impl DecodeV2 for BzDecoder {
5764
fn reinit(&mut self) -> io::Result<()> {
5865
self.decompress = Decompress::new(false);
66+
self.stream_ended = false;
5967
Ok(())
6068
}
6169

@@ -101,6 +109,13 @@ impl DecodeV2 for BzDecoder {
101109
}
102110

103111
fn finish(&mut self, _output: &mut WriteBuffer<'_>) -> io::Result<bool> {
104-
Ok(true)
112+
if self.stream_ended {
113+
Ok(true)
114+
} else {
115+
Err(io::Error::new(
116+
io::ErrorKind::UnexpectedEof,
117+
"bzip2 stream did not finish",
118+
))
119+
}
105120
}
106121
}

0 commit comments

Comments
 (0)