Skip to content

Commit

Permalink
Merge pull request #26 from anatawa12/issue-25
Browse files Browse the repository at this point in the history
Fix panic with debug build with big copy length
  • Loading branch information
anatawa12 authored Mar 11, 2024
2 parents 2bfab78 + 8681bc9 commit b4e4b11
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ The format is based on [Keep a Changelog].
### Removed

### Fixed
- Panic with Invalid Data `#26` `#24`

### Security

Expand Down
10 changes: 9 additions & 1 deletion src/inflater_managed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ static STATIC_DISTANCE_TREE_TABLE: &[u8] = &[
0x01, 0x11, 0x09, 0x19, 0x05, 0x15, 0x0d, 0x1d, 0x03, 0x13, 0x0b, 0x1b, 0x07, 0x17, 0x0f, 0x1f,
];

// source: https://github.com/dotnet/runtime/blob/82dac28143be0740d795f434db9b70f61b3b7a04/src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateManaged/OutputWindow.cs#L17
const TABLE_LOOKUP_LENGTH_MAX: usize = 65536;
const TABLE_LOOKUP_DISTANCE_MAX: usize = 65538;

/// The streaming Inflater for deflate64
///
/// This struct has big buffer so It's not recommended to move this struct.
Expand Down Expand Up @@ -326,7 +330,7 @@ impl InflaterManaged {
*end_of_block_code_seen = false;

let mut free_bytes = self.output.free_bytes(); // it is a little bit faster than frequently accessing the property
while free_bytes > 65536 {
while free_bytes > TABLE_LOOKUP_LENGTH_MAX {
// With Deflate64 we can have up to a 64kb length, so we ensure at least that much space is available
// in the OutputWindow to avoid overwriting previous unflushed output data.

Expand Down Expand Up @@ -412,6 +416,10 @@ impl InflaterManaged {
offset = (self.distance_code + 1) as usize;
}

if self.length > TABLE_LOOKUP_LENGTH_MAX || offset > TABLE_LOOKUP_DISTANCE_MAX {
return Err(InternalErr::DataError);
}

self.output.write_length_distance(self.length, offset);
free_bytes -= self.length;
self.state = InflaterState::DecodeTop;
Expand Down
Binary file added test-assets/issue-25/deflate64_not_enough_space.zip
Binary file not shown.
25 changes: 25 additions & 0 deletions tests/issue-25.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use deflate64::InflaterManaged;

static ZIP_FILE_DATA: &[u8] =
include_bytes!("../test-assets/issue-25/deflate64_not_enough_space.zip");

fn deflate64_data() -> &'static [u8] {
&ZIP_FILE_DATA[30..]
}

// panic with invalid deflate64 data (too big lookup length)

#[test]
fn issue_25() {
let compressed_data = deflate64_data();

let mut inflater = Box::new(InflaterManaged::new());
let mut sink = vec![0u8; 1024 * 1024 * 4];

let output = inflater.inflate(compressed_data, &mut sink);

assert!(
output.data_error,
"expected an error since this deflate64 file is invalid"
);
}

0 comments on commit b4e4b11

Please sign in to comment.