-
-
Notifications
You must be signed in to change notification settings - Fork 41
Inflater::total_out() overflows 32-bit integer boundary on Windows despite being u64 #472
Description
When unpacking a large gzipped file on Windows, total_out "overflows" after decompressing past 4 GiB.
For example, if I create a file with compressed zeros (on Linux) like this:
head -c $((5 * 1024 * 1024 * 1024)) /dev/zero | gzip -1 > zeros.gzand then try to decompress that on Windows with the code below, then flate2 panics due to subtraction overflow on:
Although the panic is in flate2, I think the issue is in zlib-rs. I tried adding a short log line there and it shows total_out is wrapping over a 32-bit boundary, going from 4294959496 to 392.
It seems that total_out has type z_size:
zlib-rs/zlib-rs/src/inflate.rs
Line 46 in a2c262f
| pub(crate) total_out: crate::c_api::z_size, |
and z_size is an alias for c_ulong:
Line 126 in a2c262f
| pub(crate) type z_size = c_ulong; |
but c_ulong is a 32-bit integer on Windows systems, even if the host is 64-bit. Would it make sense for total_out (and maybe total_in?) to be a type that's always 64 bits?
Thanks!
Reproducer:
use std::{env, fs::File, io::Read, path::PathBuf};
use flate2::read::GzDecoder;
fn main() {
let input_path = PathBuf::from(env::args_os().skip(1).next().unwrap());
let file = File::open(&input_path).unwrap();
let mut decoder = GzDecoder::new(file);
let mut buf = [0u8; 8192];
loop {
let n = decoder.read(&mut buf).unwrap();
if n == 0 {
break;
}
}
}