Skip to content

Commit e012985

Browse files
committed
Add support for reading the ending ZIP file comment
1 parent aa10141 commit e012985

File tree

5 files changed

+24
-10
lines changed

5 files changed

+24
-10
lines changed

src/read/fs.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,16 @@ use async_io_utilities::AsyncDelimiterReader;
3737
pub struct ZipFileReader {
3838
pub(crate) filename: String,
3939
pub(crate) entries: Vec<ZipEntry>,
40+
pub(crate) comment: Option<String>,
4041
}
4142

4243
impl ZipFileReader {
4344
/// Constructs a new ZIP file reader from a filename.
4445
pub async fn new(filename: String) -> Result<ZipFileReader> {
4546
let mut fs_file = File::open(&filename).await?;
46-
let entries = crate::read::seek::read_cd(&mut fs_file).await?;
47+
let (entries, comment) = crate::read::seek::read_cd(&mut fs_file).await?;
4748

48-
Ok(ZipFileReader { filename, entries })
49+
Ok(ZipFileReader { filename, entries, comment })
4950
}
5051

5152
crate::read::reader_entry_impl!();

src/read/mem.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,14 @@ pub type ConcurrentReader<'b, 'a> = ZipEntryReader<'b, Cursor<&'a [u8]>>;
1919
pub struct ZipFileReader<'a> {
2020
pub(crate) data: &'a [u8],
2121
pub(crate) entries: Vec<ZipEntry>,
22+
pub(crate) comment: Option<String>,
2223
}
2324

2425
impl<'a> ZipFileReader<'a> {
2526
/// Constructs a new ZIP file reader from an in-memory buffer.
2627
pub async fn new(data: &'a [u8]) -> Result<ZipFileReader<'a>> {
27-
let entries = crate::read::seek::read_cd(&mut Cursor::new(data)).await?;
28-
Ok(ZipFileReader { data, entries })
28+
let (entries, comment) = crate::read::seek::read_cd(&mut Cursor::new(data)).await?;
29+
Ok(ZipFileReader { data, entries, comment })
2930
}
3031

3132
crate::read::reader_entry_impl!();

src/read/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,11 @@ macro_rules! reader_entry_impl {
347347
}
348348
None
349349
}
350+
351+
/// Returns an optional ending comment.
352+
pub fn comment(&self) -> Option<&str> {
353+
self.comment.as_ref().map(|x| &x[..])
354+
}
350355
};
351356
}
352357

src/read/seek.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,14 @@ use async_io_utilities::AsyncDelimiterReader;
3939
pub struct ZipFileReader<R: AsyncRead + AsyncSeek + Unpin> {
4040
pub(crate) reader: R,
4141
pub(crate) entries: Vec<ZipEntry>,
42+
pub(crate) comment: Option<String>,
4243
}
4344

4445
impl<R: AsyncRead + AsyncSeek + Unpin> ZipFileReader<R> {
4546
/// Constructs a new ZIP file reader from a mutable reference to a reader.
4647
pub async fn new(mut reader: R) -> Result<ZipFileReader<R>> {
47-
let entries = read_cd(&mut reader).await?;
48-
Ok(ZipFileReader { reader, entries })
48+
let (entries, comment) = read_cd(&mut reader).await?;
49+
Ok(ZipFileReader { reader, entries, comment })
4950
}
5051

5152
crate::read::reader_entry_impl!();
@@ -79,7 +80,7 @@ impl<R: AsyncRead + AsyncSeek + Unpin> ZipFileReader<R> {
7980
}
8081
}
8182

82-
pub(crate) async fn read_cd<R: AsyncRead + AsyncSeek + Unpin>(reader: &mut R) -> Result<Vec<ZipEntry>> {
83+
pub(crate) async fn read_cd<R: AsyncRead + AsyncSeek + Unpin>(reader: &mut R) -> Result<(Vec<ZipEntry>, Option<String>)> {
8384
const MAX_ENDING_LENGTH: u64 = (u16::MAX - 2) as u64;
8485

8586
let length = reader.seek(SeekFrom::End(0)).await?;
@@ -90,6 +91,7 @@ pub(crate) async fn read_cd<R: AsyncRead + AsyncSeek + Unpin>(reader: &mut R) ->
9091

9192
reader.seek(SeekFrom::Start(seek_to)).await?;
9293

94+
let mut comment = None;
9395
let delimiter = crate::spec::signature::END_OF_CENTRAL_DIRECTORY.to_le_bytes();
9496
let mut reader = AsyncDelimiterReader::new(reader, &delimiter);
9597

@@ -112,6 +114,10 @@ pub(crate) async fn read_cd<R: AsyncRead + AsyncSeek + Unpin>(reader: &mut R) ->
112114
return Err(ZipError::FeatureNotSupported("Spanned/split files"));
113115
}
114116

117+
if eocdh.file_comm_length > 0 {
118+
comment = Some(crate::utils::read_string(&mut reader, eocdh.file_comm_length as usize).await?);
119+
}
120+
115121
let reader = reader.into_inner();
116122
reader.seek(SeekFrom::Start(eocdh.cent_dir_offset.into())).await?;
117123
let mut entries = Vec::with_capacity(eocdh.num_of_entries.into());
@@ -120,7 +126,7 @@ pub(crate) async fn read_cd<R: AsyncRead + AsyncSeek + Unpin>(reader: &mut R) ->
120126
entries.push(read_cd_entry(reader).await?);
121127
}
122128

123-
Ok(entries)
129+
Ok((entries, comment))
124130
}
125131

126132
pub(crate) async fn read_cd_entry<R: AsyncRead + Unpin>(reader: &mut R) -> Result<ZipEntry> {

src/read/sync.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use async_io_utilities::AsyncDelimiterReader;
3131
pub struct ZipFileReader<R: AsyncRead + AsyncSeek + Unpin> {
3232
pub(crate) reader: Arc<Mutex<R>>,
3333
pub(crate) entries: Vec<ZipEntry>,
34+
pub(crate) comment: Option<String>,
3435
}
3536

3637
#[allow(unreachable_code, unused_variables)]
@@ -39,8 +40,8 @@ impl<R: AsyncRead + AsyncSeek + Unpin> ZipFileReader<R> {
3940
pub async fn new(reader: R) -> Result<ZipFileReader<R>> {
4041
unimplemented!();
4142

42-
let entries = crate::read::seek::read_cd(&mut reader).await?;
43-
Ok(ZipFileReader { reader: Arc::new(Mutex::new(reader)), entries })
43+
let (entries, comment) = crate::read::seek::read_cd(&mut reader).await?;
44+
Ok(ZipFileReader { reader: Arc::new(Mutex::new(reader)), entries, comment })
4445
}
4546

4647
crate::read::reader_entry_impl!();

0 commit comments

Comments
 (0)