chore: Fix merge

This commit is contained in:
Chris Hennick 2024-05-05 17:53:18 -07:00
parent 40b0af9494
commit 614879506c
No known key found for this signature in database
GPG key ID: DA47AABA4961C509
4 changed files with 49 additions and 46 deletions

View file

@ -28,8 +28,8 @@
#![warn(missing_docs)] #![warn(missing_docs)]
pub use crate::compression::{CompressionMethod, SUPPORTED_COMPRESSION_METHODS}; pub use crate::compression::{CompressionMethod, SUPPORTED_COMPRESSION_METHODS};
pub use crate::read::ZipArchive;
pub use crate::read::HasZipMetadata; pub use crate::read::HasZipMetadata;
pub use crate::read::ZipArchive;
pub use crate::types::DateTime; pub use crate::types::DateTime;
pub use crate::write::ZipWriter; pub use crate::write::ZipWriter;

View file

@ -12,8 +12,7 @@ use crate::spec;
use crate::types::{AesMode, AesVendorVersion, DateTime, System, ZipFileData}; use crate::types::{AesMode, AesVendorVersion, DateTime, System, ZipFileData};
use crate::zipcrypto::{ZipCryptoReader, ZipCryptoReaderValid, ZipCryptoValidator}; use crate::zipcrypto::{ZipCryptoReader, ZipCryptoReaderValid, ZipCryptoValidator};
use indexmap::IndexMap; use indexmap::IndexMap;
use std::borrow::{Borrow, Cow}; use std::borrow::Cow;
use std::collections::HashMap;
use std::io::{self, prelude::*, SeekFrom}; use std::io::{self, prelude::*, SeekFrom};
use std::ops::Deref; use std::ops::Deref;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@ -221,20 +220,19 @@ struct SeekableTake<'a, R> {
current_offset: u64, current_offset: u64,
} }
impl<'a, R: Seek> SeekableTake<'a, R> {
impl <'a, R: Seek> SeekableTake<'a, R> {
pub fn new(inner: &'a mut R, length: u64) -> io::Result<Self> { pub fn new(inner: &'a mut R, length: u64) -> io::Result<Self> {
let inner_starting_offset = inner.seek(SeekFrom::Current(0))?; let inner_starting_offset = inner.stream_position()?;
Ok(Self { Ok(Self {
inner, inner,
inner_starting_offset, inner_starting_offset,
length, length,
current_offset: 0 current_offset: 0,
}) })
} }
} }
impl <'a, R: Seek> Seek for SeekableTake<'a, R> { impl<'a, R: Seek> Seek for SeekableTake<'a, R> {
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
let offset = match pos { let offset = match pos {
SeekFrom::Start(offset) => Some(offset), SeekFrom::Start(offset) => Some(offset),
@ -242,12 +240,15 @@ impl <'a, R: Seek> Seek for SeekableTake<'a, R> {
SeekFrom::Current(offset) => self.current_offset.checked_add_signed(offset), SeekFrom::Current(offset) => self.current_offset.checked_add_signed(offset),
}; };
match offset { match offset {
None => { None => Err(io::Error::new(
Err(io::Error::new(io::ErrorKind::InvalidInput, "invalid seek to a negative or overflowing position")) io::ErrorKind::InvalidInput,
} "invalid seek to a negative or overflowing position",
)),
Some(offset) => { Some(offset) => {
let clamped_offset = std::cmp::min(self.length, offset); let clamped_offset = std::cmp::min(self.length, offset);
let new_inner_offset = self.inner.seek(SeekFrom::Start(self.inner_starting_offset + clamped_offset))?; let new_inner_offset = self
.inner
.seek(SeekFrom::Start(self.inner_starting_offset + clamped_offset))?;
self.current_offset = new_inner_offset - self.inner_starting_offset; self.current_offset = new_inner_offset - self.inner_starting_offset;
Ok(new_inner_offset) Ok(new_inner_offset)
} }
@ -255,9 +256,12 @@ impl <'a, R: Seek> Seek for SeekableTake<'a, R> {
} }
} }
impl <'a, R: Read> Read for SeekableTake<'a, R> { impl<'a, R: Read> Read for SeekableTake<'a, R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let written = self.inner.take(self.length - self.current_offset).read(buf)?; let written = self
.inner
.take(self.length - self.current_offset)
.read(buf)?;
self.current_offset += written as u64; self.current_offset += written as u64;
Ok(written) Ok(written)
} }
@ -297,17 +301,17 @@ fn find_content_seek<'a, R: Read + Seek>(
) -> ZipResult<SeekableTake<'a, R>> { ) -> ZipResult<SeekableTake<'a, R>> {
// Parse local header // Parse local header
reader.seek(io::SeekFrom::Start(data.header_start))?; reader.seek(io::SeekFrom::Start(data.header_start))?;
let signature = reader.read_u32::<LittleEndian>()?; let signature = reader.read_u32_le()?;
if signature != spec::LOCAL_FILE_HEADER_SIGNATURE { if signature != spec::LOCAL_FILE_HEADER_SIGNATURE {
return Err(ZipError::InvalidArchive("Invalid local file header")); return Err(ZipError::InvalidArchive("Invalid local file header"));
} }
reader.seek(io::SeekFrom::Current(22))?; reader.seek(io::SeekFrom::Current(22))?;
let file_name_length = reader.read_u16::<LittleEndian>()? as u64; let file_name_length = reader.read_u16_le()? as u64;
let extra_field_length = reader.read_u16::<LittleEndian>()? as u64; let extra_field_length = reader.read_u16_le()? as u64;
let magic_and_header = 4 + 22 + 2 + 2; let magic_and_header = 4 + 22 + 2 + 2;
let data_start = data.header_start + magic_and_header + file_name_length + extra_field_length; let data_start = data.header_start + magic_and_header + file_name_length + extra_field_length;
data.data_start.store(data_start); data.data_start.get_or_init(|| data_start);
reader.seek(io::SeekFrom::Start(data_start))?; reader.seek(io::SeekFrom::Start(data_start))?;
@ -822,13 +826,7 @@ impl<R: Read + Seek> ZipArchive<R> {
/// Search for a file entry by name and return a seekable object. /// Search for a file entry by name and return a seekable object.
pub fn by_name_seek(&mut self, name: &str) -> ZipResult<ZipFileSeek<R>> { pub fn by_name_seek(&mut self, name: &str) -> ZipResult<ZipFileSeek<R>> {
let index = match self.shared.names_map.get(name) { self.by_index_seek(self.index_for_name(name).ok_or(ZipError::FileNotFound)?)
Some(index) => *index,
None => {
return Err(ZipError::FileNotFound);
}
};
self.by_index_seek(index)
} }
/// Search for a file entry by index and return a seekable object. /// Search for a file entry by index and return a seekable object.
@ -836,15 +834,17 @@ impl<R: Read + Seek> ZipArchive<R> {
let reader = &mut self.reader; let reader = &mut self.reader;
self.shared self.shared
.files .files
.get(index) .get_index(index)
.ok_or(ZipError::FileNotFound) .ok_or(ZipError::FileNotFound)
.and_then(move |data| { .and_then(move |(_, data)| {
let seek_reader = match data.compression_method { let seek_reader = match data.compression_method {
CompressionMethod::Stored => { CompressionMethod::Stored => {
ZipFileSeekReader::Raw(find_content_seek(data, reader)?) ZipFileSeekReader::Raw(find_content_seek(data, reader)?)
} }
_ => { _ => {
return Err(ZipError::UnsupportedArchive("Seekable compressed files are not yet supported")) return Err(ZipError::UnsupportedArchive(
"Seekable compressed files are not yet supported",
))
} }
}; };
Ok(ZipFileSeek { Ok(ZipFileSeek {
@ -1272,7 +1272,10 @@ pub trait HasZipMetadata {
/// Get the extra data of the zip header for this file /// Get the extra data of the zip header for this file
fn extra_data(&self) -> Option<&[u8]> { fn extra_data(&self) -> Option<&[u8]> {
self.get_metadata().extra_field.as_ref().map(|v| v.deref().deref()) self.get_metadata()
.extra_field
.as_ref()
.map(|v| v.deref().deref())
} }
/// Get the starting offset of the data of the compressed file /// Get the starting offset of the data of the compressed file
@ -1308,12 +1311,6 @@ impl<'a> ZipFile<'a> {
} }
&mut self.reader &mut self.reader
} }
}
impl <'a> HasZipMetadata for ZipFile<'a> {
fn get_metadata(&self) -> &ZipFileData {
self.data.as_ref()
}
/// iterate through all extra fields /// iterate through all extra fields
pub fn extra_data_fields(&self) -> impl Iterator<Item = &ExtraField> { pub fn extra_data_fields(&self) -> impl Iterator<Item = &ExtraField> {
@ -1321,13 +1318,19 @@ impl <'a> HasZipMetadata for ZipFile<'a> {
} }
} }
impl<'a> HasZipMetadata for ZipFile<'a> {
fn get_metadata(&self) -> &ZipFileData {
self.data.as_ref()
}
}
impl<'a> Read for ZipFile<'a> { impl<'a> Read for ZipFile<'a> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.get_reader().read(buf) self.get_reader().read(buf)
} }
} }
impl <'a, R: Read> Read for ZipFileSeek<'a, R> { impl<'a, R: Read> Read for ZipFileSeek<'a, R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
match &mut self.reader { match &mut self.reader {
ZipFileSeekReader::Raw(r) => r.read(buf), ZipFileSeekReader::Raw(r) => r.read(buf),
@ -1335,7 +1338,7 @@ impl <'a, R: Read> Read for ZipFileSeek<'a, R> {
} }
} }
impl <'a, R: Seek> Seek for ZipFileSeek<'a, R> { impl<'a, R: Seek> Seek for ZipFileSeek<'a, R> {
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
match &mut self.reader { match &mut self.reader {
ZipFileSeekReader::Raw(r) => r.seek(pos), ZipFileSeekReader::Raw(r) => r.seek(pos),
@ -1343,7 +1346,7 @@ impl <'a, R: Seek> Seek for ZipFileSeek<'a, R> {
} }
} }
impl <'a, R> HasZipMetadata for ZipFileSeek<'a, R> { impl<'a, R> HasZipMetadata for ZipFileSeek<'a, R> {
fn get_metadata(&self) -> &ZipFileData { fn get_metadata(&self) -> &ZipFileData {
self.data.as_ref() self.data.as_ref()
} }
@ -1534,8 +1537,8 @@ mod test {
#[test] #[test]
fn zip_contents() { fn zip_contents() {
use super::ZipArchive;
use super::HasZipMetadata; use super::HasZipMetadata;
use super::ZipArchive;
let mut v = Vec::new(); let mut v = Vec::new();
v.extend_from_slice(include_bytes!("../tests/data/mimetype.zip")); v.extend_from_slice(include_bytes!("../tests/data/mimetype.zip"));
@ -1560,8 +1563,8 @@ mod test {
#[test] #[test]
fn zip_clone() { fn zip_clone() {
use super::ZipArchive;
use super::HasZipMetadata; use super::HasZipMetadata;
use super::ZipArchive;
use std::io::Read; use std::io::Read;
let mut v = Vec::new(); let mut v = Vec::new();
@ -1602,8 +1605,8 @@ mod test {
#[test] #[test]
fn file_and_dir_predicates() { fn file_and_dir_predicates() {
use super::ZipArchive;
use super::HasZipMetadata; use super::HasZipMetadata;
use super::ZipArchive;
let mut v = Vec::new(); let mut v = Vec::new();
v.extend_from_slice(include_bytes!("../tests/data/files_and_dirs.zip")); v.extend_from_slice(include_bytes!("../tests/data/files_and_dirs.zip"));

View file

@ -4,8 +4,8 @@ use std::io::{self, Read};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use super::{ use super::{
central_header_to_zip_file_inner, read_zipfile_from_stream, spec, ZipError, ZipFile, central_header_to_zip_file_inner, read_zipfile_from_stream, spec, HasZipMetadata, ZipError,
ZipFileData, ZipResult, HasZipMetadata, ZipFile, ZipFileData, ZipResult,
}; };
/// Stream decoder for zip. /// Stream decoder for zip.

View file

@ -1,9 +1,9 @@
//! Types for creating ZIP archives //! Types for creating ZIP archives
use crate::compression::CompressionMethod; use crate::compression::CompressionMethod;
use crate::read::{find_content, central_header_to_zip_file, ZipArchive, ZipFile}; use crate::read::{find_content, ZipArchive, ZipFile, ZipFileReader};
use crate::result::{ZipError, ZipResult}; use crate::result::{ZipError, ZipResult};
use crate::spec; use crate::{HasZipMetadata, spec};
use crate::types::{ffi, DateTime, System, ZipFileData, DEFAULT_VERSION}; use crate::types::{ffi, DateTime, System, ZipFileData, DEFAULT_VERSION};
#[cfg(any(feature = "_deflate-any", feature = "bzip2", feature = "zstd",))] #[cfg(any(feature = "_deflate-any", feature = "bzip2", feature = "zstd",))]
use core::num::NonZeroU64; use core::num::NonZeroU64;
@ -1810,7 +1810,7 @@ mod test {
use crate::types::DateTime; use crate::types::DateTime;
use crate::write::SimpleFileOptions; use crate::write::SimpleFileOptions;
use crate::CompressionMethod::Stored; use crate::CompressionMethod::Stored;
use crate::ZipArchive; use crate::{HasZipMetadata, ZipArchive};
use std::io; use std::io;
use std::io::{Cursor, Read, Write}; use std::io::{Cursor, Read, Write};
use std::path::PathBuf; use std::path::PathBuf;