Skip to content

feat: add read_zipfile_from_stream_with_compressed_size #70

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions src/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1371,6 +1371,104 @@
}))
}

pub fn read_zipfile_from_stream_with_compressed_size<'a, R: io::Read>(
reader: &'a mut R,
compressed_size: u64
) -> ZipResult<Option<ZipFile<'_>>> {
let signature = reader.read_u32::<LittleEndian>()?;

Check failure on line 1378 in src/read.rs

View workflow job for this annotation

GitHub Actions / Build and test --no-default-features: ubuntu-latest, msrv

cannot find type `LittleEndian` in this scope

Check failure on line 1378 in src/read.rs

View workflow job for this annotation

GitHub Actions / style_and_docs (--no-default-features)

cannot find type `LittleEndian` in this scope

Check failure on line 1378 in src/read.rs

View workflow job for this annotation

GitHub Actions / Build and test --no-default-features: macOS-latest, msrv

cannot find type `LittleEndian` in this scope

match signature {
spec::LOCAL_FILE_HEADER_SIGNATURE => (),
spec::CENTRAL_DIRECTORY_HEADER_SIGNATURE => return Ok(None),
_ => return Err(ZipError::InvalidArchive("Invalid local file header")),
}

let version_made_by = reader.read_u16::<LittleEndian>()?;

Check failure on line 1386 in src/read.rs

View workflow job for this annotation

GitHub Actions / Build and test --no-default-features: ubuntu-latest, msrv

cannot find type `LittleEndian` in this scope

Check failure on line 1386 in src/read.rs

View workflow job for this annotation

GitHub Actions / style_and_docs (--no-default-features)

cannot find type `LittleEndian` in this scope

Check failure on line 1386 in src/read.rs

View workflow job for this annotation

GitHub Actions / Build and test --no-default-features: macOS-latest, msrv

cannot find type `LittleEndian` in this scope
let flags = reader.read_u16::<LittleEndian>()?;

Check failure on line 1387 in src/read.rs

View workflow job for this annotation

GitHub Actions / Build and test --no-default-features: ubuntu-latest, msrv

cannot find type `LittleEndian` in this scope

Check failure on line 1387 in src/read.rs

View workflow job for this annotation

GitHub Actions / style_and_docs (--no-default-features)

cannot find type `LittleEndian` in this scope

Check failure on line 1387 in src/read.rs

View workflow job for this annotation

GitHub Actions / Build and test --no-default-features: macOS-latest, msrv

cannot find type `LittleEndian` in this scope
let encrypted = flags & 1 == 1;
let is_utf8 = flags & (1 << 11) != 0;
let using_data_descriptor = flags & (1 << 3) != 0;
#[allow(deprecated)]
let compression_method = CompressionMethod::from_u16(reader.read_u16::<LittleEndian>()?);

Check failure on line 1392 in src/read.rs

View workflow job for this annotation

GitHub Actions / Build and test --no-default-features: ubuntu-latest, msrv

cannot find type `LittleEndian` in this scope

Check failure on line 1392 in src/read.rs

View workflow job for this annotation

GitHub Actions / style_and_docs (--no-default-features)

cannot find type `LittleEndian` in this scope

Check failure on line 1392 in src/read.rs

View workflow job for this annotation

GitHub Actions / Build and test --no-default-features: macOS-latest, msrv

cannot find type `LittleEndian` in this scope
let last_mod_time = reader.read_u16::<LittleEndian>()?;

Check failure on line 1393 in src/read.rs

View workflow job for this annotation

GitHub Actions / Build and test --no-default-features: ubuntu-latest, msrv

cannot find type `LittleEndian` in this scope

Check failure on line 1393 in src/read.rs

View workflow job for this annotation

GitHub Actions / style_and_docs (--no-default-features)

cannot find type `LittleEndian` in this scope

Check failure on line 1393 in src/read.rs

View workflow job for this annotation

GitHub Actions / Build and test --no-default-features: macOS-latest, msrv

cannot find type `LittleEndian` in this scope
let last_mod_date = reader.read_u16::<LittleEndian>()?;

Check failure on line 1394 in src/read.rs

View workflow job for this annotation

GitHub Actions / Build and test --no-default-features: ubuntu-latest, msrv

cannot find type `LittleEndian` in this scope

Check failure on line 1394 in src/read.rs

View workflow job for this annotation

GitHub Actions / style_and_docs (--no-default-features)

cannot find type `LittleEndian` in this scope

Check failure on line 1394 in src/read.rs

View workflow job for this annotation

GitHub Actions / Build and test --no-default-features: macOS-latest, msrv

cannot find type `LittleEndian` in this scope
let crc32 = reader.read_u32::<LittleEndian>()?;

Check failure on line 1395 in src/read.rs

View workflow job for this annotation

GitHub Actions / Build and test --no-default-features: ubuntu-latest, msrv

cannot find type `LittleEndian` in this scope

Check failure on line 1395 in src/read.rs

View workflow job for this annotation

GitHub Actions / style_and_docs (--no-default-features)

cannot find type `LittleEndian` in this scope

Check failure on line 1395 in src/read.rs

View workflow job for this annotation

GitHub Actions / Build and test --no-default-features: macOS-latest, msrv

cannot find type `LittleEndian` in this scope
let _compressed_size = reader.read_u32::<LittleEndian>()?;

Check failure on line 1396 in src/read.rs

View workflow job for this annotation

GitHub Actions / Build and test --no-default-features: ubuntu-latest, msrv

cannot find type `LittleEndian` in this scope

Check failure on line 1396 in src/read.rs

View workflow job for this annotation

GitHub Actions / style_and_docs (--no-default-features)

cannot find type `LittleEndian` in this scope

Check failure on line 1396 in src/read.rs

View workflow job for this annotation

GitHub Actions / Build and test --no-default-features: macOS-latest, msrv

cannot find type `LittleEndian` in this scope
let uncompressed_size = reader.read_u32::<LittleEndian>()?;

Check failure on line 1397 in src/read.rs

View workflow job for this annotation

GitHub Actions / Build and test --no-default-features: ubuntu-latest, msrv

cannot find type `LittleEndian` in this scope

Check failure on line 1397 in src/read.rs

View workflow job for this annotation

GitHub Actions / style_and_docs (--no-default-features)

cannot find type `LittleEndian` in this scope

Check failure on line 1397 in src/read.rs

View workflow job for this annotation

GitHub Actions / Build and test --no-default-features: macOS-latest, msrv

cannot find type `LittleEndian` in this scope
let file_name_length = reader.read_u16::<LittleEndian>()? as usize;

Check failure on line 1398 in src/read.rs

View workflow job for this annotation

GitHub Actions / Build and test --no-default-features: ubuntu-latest, msrv

cannot find type `LittleEndian` in this scope

Check failure on line 1398 in src/read.rs

View workflow job for this annotation

GitHub Actions / style_and_docs (--no-default-features)

cannot find type `LittleEndian` in this scope

Check failure on line 1398 in src/read.rs

View workflow job for this annotation

GitHub Actions / Build and test --no-default-features: macOS-latest, msrv

cannot find type `LittleEndian` in this scope
let extra_field_length = reader.read_u16::<LittleEndian>()? as usize;

let mut file_name_raw = vec![0; file_name_length];
reader.read_exact(&mut file_name_raw)?;
let mut extra_field = vec![0; extra_field_length];
reader.read_exact(&mut extra_field)?;

let file_name = match is_utf8 {
true => String::from_utf8_lossy(&file_name_raw).into_owned(),
false => file_name_raw.clone().from_cp437(),
};

let mut result = ZipFileData {
system: System::from_u8((version_made_by >> 8) as u8),
version_made_by: version_made_by as u8,
encrypted,
using_data_descriptor,
compression_method,
compression_level: None,
last_modified_time: DateTime::from_msdos(last_mod_date, last_mod_time),
crc32,
compressed_size: compressed_size as u64,
uncompressed_size: uncompressed_size as u64,
file_name,
file_name_raw,
extra_field,
file_comment: String::new(), // file comment is only available in the central directory
// header_start and data start are not available, but also don't matter, since seeking is
// not available.
header_start: 0,
data_start: AtomicU64::new(0),
central_header_start: 0,
// The external_attributes field is only available in the central directory.
// We set this to zero, which should be valid as the docs state 'If input came
// from standard input, this field is set to zero.'
external_attributes: 0,
large_file: false,
aes_mode: None,
};

match parse_extra_field(&mut result) {
Ok(..) | Err(ZipError::Io(..)) => {}
Err(e) => return Err(e),
}

if encrypted {
return unsupported_zip_error("Encrypted files are not supported");
}

let limit_reader = (reader as &'a mut dyn io::Read).take(result.compressed_size);

let result_crc32 = result.crc32;
let result_compression_method = result.compression_method;
let crypto_reader = make_crypto_reader(
result_compression_method,
result_crc32,
result.last_modified_time,
result.using_data_descriptor,
limit_reader,
None,
None,
#[cfg(feature = "aes-crypto")]
result.compressed_size,
)?
.unwrap();

Ok(Some(ZipFile {
data: Cow::Owned(result),
crypto_reader: None,
reader: make_reader(result_compression_method, result_crc32, crypto_reader),
}))
}

#[cfg(test)]
mod test {
use crate::ZipArchive;
Expand Down
Loading