Skip to content

Commit

Permalink
Tests pass
Browse files Browse the repository at this point in the history
  • Loading branch information
fasterthanlime committed Jan 30, 2024
1 parent 22266de commit 3f7e946
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 16 deletions.
4 changes: 2 additions & 2 deletions crates/rc-zip/src/format/date_time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ impl NtfsTimestamp {
// windows timestamp resolution
let ticks_per_second = 10_000_000;
let secs = (self.timestamp / ticks_per_second) as i64;
let nsecs = (1_000_000_000 / ticks_per_second) * (self.timestamp * ticks_per_second);
let nsecs = ((self.timestamp % ticks_per_second) * 100) as u32;
let epoch = Utc.with_ymd_and_hms(1601, 1, 1, 0, 0, 0).single()?;
match Utc.timestamp_opt(epoch.timestamp() + secs, nsecs as u32) {
match Utc.timestamp_opt(epoch.timestamp() + secs, nsecs) {
LocalResult::Single(date) => Some(date),
_ => None,
}
Expand Down
27 changes: 18 additions & 9 deletions crates/rc-zip/src/format/extra_field.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::format::*;
use tracing::trace;
use winnow::{
binary::{le_u16, le_u32, le_u64, le_u8, length_take},
combinator::{cond, opt, preceded, repeat},
error::{ErrMode, ErrorKind, ParserError},
combinator::{cond, opt, preceded, repeat_till},
error::{ErrMode, ErrorKind, ParserError, StrContext},
seq,
token::{tag, take},
PResult, Parser, Partial,
Expand Down Expand Up @@ -66,15 +67,16 @@ impl ExtraField {
move |i| {
use ExtraField as EF;
let rec = ExtraFieldRecord::parser.parse_next(i)?;
trace!("parsing extra field record, tag {:04x}", rec.tag);
let payload = &mut Partial::new(rec.payload);

let variant = match rec.tag {
ExtraZip64Field::TAG => {
opt(ExtraZip64Field::mk_parser(settings).map(EF::Zip64)).parse_next(payload)?
}
ExtraTimestampField::TAG => {
opt(ExtraTimestampField::parser.map(EF::Timestamp)).parse_next(payload)?
}
ExtraZip64Field::TAG => opt(ExtraZip64Field::mk_parser(settings).map(EF::Zip64))
.context(StrContext::Label("zip64"))
.parse_next(payload)?,
ExtraTimestampField::TAG => opt(ExtraTimestampField::parser.map(EF::Timestamp))
.context(StrContext::Label("timestamp"))
.parse_next(payload)?,
ExtraNtfsField::TAG => {
opt(ExtraNtfsField::parse.map(EF::Ntfs)).parse_next(payload)?
}
Expand Down Expand Up @@ -234,7 +236,12 @@ impl ExtraNtfsField {
fn parse(i: &mut Partial<&'_ [u8]>) -> PResult<Self> {
let _ = take(4_usize).parse_next(i)?; // reserved (unused)
seq! {Self {
attrs: repeat(0.., NtfsAttr::parse),
// from the winnow docs:
// Parsers like repeat do not know when an eof is from insufficient
// data or the end of the stream, causing them to always report
// Incomplete.
// using repeat_till with eof combinator to work around this:
attrs: repeat_till(0.., NtfsAttr::parse, winnow::combinator::eof).map(|x| x.0),
}}
.parse_next(i)
}
Expand All @@ -250,6 +257,7 @@ pub enum NtfsAttr {
impl NtfsAttr {
fn parse(i: &mut Partial<&'_ [u8]>) -> PResult<Self> {
let tag = le_u16.parse_next(i)?;
trace!("parsing NTFS attribute, tag {:04x}", tag);
let payload = length_take(le_u16).parse_next(i)?;

match tag {
Expand All @@ -270,6 +278,7 @@ pub struct NtfsAttr1 {

impl NtfsAttr1 {
fn parser(i: &mut Partial<&'_ [u8]>) -> PResult<Self> {
trace!("parsing NTFS attr 1, input len is {}", i.len());
seq! {Self {
mtime: NtfsTimestamp::parser,
atime: NtfsTimestamp::parser,
Expand Down
14 changes: 13 additions & 1 deletion crates/rc-zip/src/reader/archive_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,13 +289,25 @@ impl ArchiveReader {
buffer.available_data()
);
let mut input = Partial::new(buffer.data());
trace!(
initial_offset = input.as_bytes().offset_from(&buffer.data()),
initial_len = input.len(),
"initial offset & len"
);
'read_headers: while !input.is_empty() {
match DirectoryHeader::parser.parse_next(&mut input) {
Ok(dh) => {
trace!(
input_empty_now = input.is_empty(),
offset = input.as_bytes().offset_from(&buffer.data()),
len = input.len(),
"ReadCentralDirectory | parsed directory header"
);
directory_headers.push(dh);
}
Err(ErrMode::Incomplete(_needed)) => {
// need more data to read the full header
trace!("ReadCentralDirectory | incomplete!");
break 'read_headers;
}
Err(ErrMode::Backtrack(_err)) | Err(ErrMode::Cut(_err)) => {
Expand Down Expand Up @@ -394,7 +406,7 @@ impl ArchiveReader {
}
}
let consumed = input.as_bytes().offset_from(&buffer.data());
tracing::trace!(%consumed, "ReadCentralDirectory done");
tracing::trace!(%consumed, "ReadCentralDirectory total consumed");
buffer.consume(consumed);

// need more data
Expand Down
9 changes: 5 additions & 4 deletions crates/rc-zip/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ fn test_cases() -> Vec<ZipTest> {
files: vec![ZipTestFile {
name: "世界",
content: FileContent::Bytes(vec![]),
modified: Some(date((2017, 11, 6), (13, 9, 26), 0, time_zone(0)).unwrap()),
modified: Some(date((2017, 11, 6), (21, 9, 27), 867862500, time_zone(0)).unwrap()),
..Default::default()
}],
..Default::default()
Expand All @@ -279,7 +279,7 @@ fn test_cases() -> Vec<ZipTest> {
files: vec![ZipTestFile {
name: "found-me.txt",
content: FileContent::Bytes("Oh no, you found me\n".repeat(5000).into()),
modified: Some(date((2024, 1, 26), (17, 14, 36), 0, time_zone(0)).unwrap()),
modified: Some(date((2024, 1, 26), (16, 14, 35), 46003100, time_zone(0)).unwrap()),
..Default::default()
}],
..Default::default()
Expand All @@ -291,7 +291,7 @@ fn test_cases() -> Vec<ZipTest> {
files: vec![ZipTestFile {
name: "found-me.txt",
content: FileContent::Bytes("Oh no, you found me\n".repeat(5000).into()),
modified: Some(date((2024, 1, 26), (17, 14, 36), 0, time_zone(0)).unwrap()),
modified: Some(date((2024, 1, 26), (16, 14, 35), 46003100, time_zone(0)).unwrap()),
..Default::default()
}],
..Default::default()
Expand All @@ -304,7 +304,7 @@ fn test_cases() -> Vec<ZipTest> {
files: vec![ZipTestFile {
name: "found-me.txt",
content: FileContent::Bytes("Oh no, you found me\n".repeat(5000).into()),
modified: Some(date((2024, 1, 26), (17, 14, 36), 0, time_zone(0)).unwrap()),
modified: Some(date((2024, 1, 26), (16, 14, 35), 46003100, time_zone(0)).unwrap()),
..Default::default()
}],
..Default::default()
Expand Down Expand Up @@ -333,6 +333,7 @@ fn read_from_file() {
#[traced_test]
fn real_world_files() {
for case in test_cases() {
eprintln!("============ testing {}", case.name());
case.check(case.bytes().read_zip());
}
}
Expand Down

0 comments on commit 3f7e946

Please sign in to comment.