Skip to content

Commit

Permalink
Tests almost pass!
Browse files Browse the repository at this point in the history
  • Loading branch information
fasterthanlime committed Jan 30, 2024
1 parent 718dda2 commit 22266de
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 44 deletions.
2 changes: 1 addition & 1 deletion crates/rc-zip/src/format/extra_field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub(crate) struct ExtraFieldRecord<'a> {
}

impl<'a> ExtraFieldRecord<'a> {
pub(crate) fn parser(i: &mut Partial<&'_ [u8]>) -> PResult<Self> {
pub(crate) fn parser(i: &mut Partial<&'a [u8]>) -> PResult<Self> {
seq! {Self {
tag: le_u16,
payload: length_take(le_u16),
Expand Down
50 changes: 26 additions & 24 deletions crates/rc-zip/src/format/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,31 +84,33 @@ pub struct DataDescriptorRecord {
impl DataDescriptorRecord {
const SIGNATURE: &'static str = "PK\x07\x08";

pub fn parser(i: &mut Partial<&'_ [u8]>, is_zip64: bool) -> PResult<Self> {
// From appnote.txt:
//
// 4.3.9.3 Although not originally assigned a signature, the value
// 0x08074b50 has commonly been adopted as a signature value for the
// data descriptor record. Implementers SHOULD be aware that ZIP files
// MAY be encountered with or without this signature marking data
// descriptors and SHOULD account for either case when reading ZIP files
// to ensure compatibility.
let _ = opt(tag(Self::SIGNATURE)).parse_next(i)?;
pub fn mk_parser(is_zip64: bool) -> impl FnMut(&mut Partial<&'_ [u8]>) -> PResult<Self> {
move |i| {
// From appnote.txt:
//
// 4.3.9.3 Although not originally assigned a signature, the value
// 0x08074b50 has commonly been adopted as a signature value for the
// data descriptor record. Implementers SHOULD be aware that ZIP files
// MAY be encountered with or without this signature marking data
// descriptors and SHOULD account for either case when reading ZIP files
// to ensure compatibility.
let _ = opt(tag(Self::SIGNATURE)).parse_next(i)?;

if is_zip64 {
seq! {Self {
crc32: le_u32,
compressed_size: le_u64,
uncompressed_size: le_u64,
}}
.parse_next(i)
} else {
seq! {Self {
crc32: le_u32,
compressed_size: le_u32.map(|x| x as u64),
uncompressed_size: le_u32.map(|x| x as u64),
}}
.parse_next(i)
if is_zip64 {
seq! {Self {
crc32: le_u32,
compressed_size: le_u64,
uncompressed_size: le_u64,
}}
.parse_next(i)
} else {
seq! {Self {
crc32: le_u32,
compressed_size: le_u32.map(|x| x as u64),
uncompressed_size: le_u32.map(|x| x as u64),
}}
.parse_next(i)
}
}
}
}
2 changes: 1 addition & 1 deletion crates/rc-zip/src/reader/archive_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ impl ArchiveReader {
}
}
S::ReadEocd64Locator { ref mut buffer, .. } => {
let mut input = Partial::new(buffer.data());
let input = Partial::new(buffer.data());
match EndOfCentralDirectory64Locator::parser.parse_peek(input) {
Err(ErrMode::Incomplete(_)) => {
// need more data
Expand Down
36 changes: 18 additions & 18 deletions crates/rc-zip/src/reader/sync/entry_reader/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ use cfg_if::cfg_if;
use oval::Buffer;
use std::io;
use tracing::trace;
use winnow::stream::Offset;
use winnow::{
error::ErrMode,
stream::{AsBytes, Offset},
Parser, Partial,
};

struct EntryReadMetrics {
uncompressed_size: u64,
Expand Down Expand Up @@ -77,10 +81,10 @@ where
let read_bytes = self.rd.read(buffer.space())?;
buffer.fill(read_bytes);

match LocalFileHeaderRecord::parser(buffer.data()) {
Ok((remaining, header)) => {
let consumed = buffer.data().offset(remaining);
buffer.consume(consumed);
let mut input = Partial::new(buffer.data());
match LocalFileHeaderRecord::parser.parse_next(&mut input) {
Ok(header) => {
buffer.consume(input.as_bytes().offset_from(&buffer.data()));

trace!("local file header: {:#?}", header);
transition!(self.state => (S::ReadLocalHeader { buffer }) {
Expand All @@ -98,6 +102,10 @@ where
});
self.read(buf)
}
Err(ErrMode::Incomplete(_)) => {
buffer.shift();
self.read(buf)
}
Err(_e) => Err(Error::Format(FormatError::InvalidLocalHeader).into()),
}
}
Expand Down Expand Up @@ -168,26 +176,18 @@ where
buffer.available_space()
);

match DataDescriptorRecord::parser(buffer.data(), self.inner.is_zip64) {
Ok((_remaining, descriptor)) => {
let mut input = Partial::new(buffer.data());
match DataDescriptorRecord::mk_parser(self.inner.is_zip64).parse_next(&mut input) {
Ok(descriptor) => {
buffer.consume(input.as_bytes().offset_from(&buffer.data()));
trace!("data descriptor = {:#?}", descriptor);
transition!(self.state => (S::ReadDataDescriptor { metrics, header, .. }) {
S::Validate { metrics, header, descriptor: Some(descriptor) }
});
self.read(buf)
}
Err(winnow::Err::Incomplete(_)) => {
trace!(
"incomplete! before shift, data {} / space {}",
buffer.available_data(),
buffer.available_space()
);
Err(ErrMode::Incomplete(_)) => {
buffer.shift();
trace!(
" after shift, data {} / space {}",
buffer.available_data(),
buffer.available_space()
);
let n = self.rd.read(buffer.space())?;
if n == 0 {
return Err(io::ErrorKind::UnexpectedEof.into());
Expand Down

0 comments on commit 22266de

Please sign in to comment.