-
Notifications
You must be signed in to change notification settings - Fork 105
fix: zip64 central header (issue 617) #629
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
Merged
Merged
Changes from all commits
Commits
Show all changes
41 commits
Select commit
Hold shift + click to select a range
1732fef
fix: zip64 central header
Its-Just-Nans 93ef7f9
rm typo
Its-Just-Nans 74e8085
revert and re-fix
Its-Just-Nans 16debc5
fmt
Its-Just-Nans 0271388
re fix
Its-Just-Nans 06b29c5
Update src/types.rs
Pr0methean 579a25d
Merge branch 'master' into fix-zip64-central-header
Pr0methean 83f0dcc
add some code
Its-Just-Nans b6ae8b0
Merge branch 'master' into fix-zip64-central-header
Its-Just-Nans ea8e004
typos
Its-Just-Nans 760beb6
comment for now
Its-Just-Nans adedb12
Merge branch 'master' into fix-zip64-central-header
Pr0methean 4f1662c
[skip ci] fix: correct ZIP64 local header update and remove debug sta…
amazon-q-developer[bot] 7c9a4d8
Update write_dir.rs: use debug formatting when logging path
Pr0methean 98eb52f
Update write_dir.rs
Pr0methean a5228c9
Merge branch 'master' into fix-zip64-central-header
Pr0methean 5e4df5a
Fix: missing closing curly
Pr0methean a17854d
Remove debug logging
Pr0methean df11cad
Merge branch 'master' into fix-zip64-central-header
Pr0methean d33488f
Fix: unclosed delimiter due to duplicated line
Pr0methean d599cfe
Fix: accidentally deleted line at start of update_local_zip64_extra_f…
Pr0methean cb3a796
Merge branch 'master' into fix-zip64-central-header
Its-Just-Nans 5857e89
add method
Its-Just-Nans b923f64
add test
Its-Just-Nans fe34f0b
Merge branch 'master' into fix-zip64-central-header
Pr0methean 7852894
Merge branch 'master' into fix-zip64-central-header
Its-Just-Nans 0b749dc
rewrite zip64 extended
Its-Just-Nans 4876ded
change mod.rs
Its-Just-Nans 33bb522
remove from enum for now
Its-Just-Nans 06eb6fb
fix zip64
Its-Just-Nans 529545e
Merge branch 'master' into fix-zip64-central-header
Its-Just-Nans a9d1f16
re update import
Its-Just-Nans 3dbf252
readd
Its-Just-Nans f3f3cb3
handle user forcing the large_file()
Its-Just-Nans 9a87097
fix and add comment to test
Its-Just-Nans 7778c1c
not on wasm
Its-Just-Nans cc381e3
fix unused
Its-Just-Nans 8fc51fe
fix imports again and again
Its-Just-Nans 7a27a73
cleanup
Its-Just-Nans f159eef
clippy
Its-Just-Nans d030fd2
fmt
Its-Just-Nans File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,165 @@ | ||
| //! 4.5.3 -Zip64 Extended Information Extra Field (0x0001) | ||
| //! | ||
| //! | Value | Size | Description | | ||
| //! | ---------------------- | ------- | -------------------------------------------- | | ||
| //! | `0x0001` | 2 bytes | Tag for this "extra" block type | | ||
| //! | Size | 2 bytes | Size of this "extra" block | | ||
| //! | Original Size | 8 bytes | Original uncompressed file size | | ||
| //! | Compressed Size | 8 bytes | Size of compressed data | | ||
| //! | Relative Header Offset | 8 bytes | Offset of local header record | | ||
| //! | Disk Start Number | 4 bytes | Number of the disk on which this file starts | | ||
| //! | ||
|
|
||
| use core::mem; | ||
|
|
||
| use crate::{ZIP64_BYTES_THR, extra_fields::UsedExtraField}; | ||
|
|
||
| /// Zip64 extended information extra field | ||
| #[derive(Copy, Clone, Debug)] | ||
| pub(crate) struct Zip64ExtendedInformation { | ||
| /// The local header does not contains any `header_start` | ||
| _is_local_header: bool, | ||
| magic: UsedExtraField, | ||
| size: u16, | ||
| uncompressed_size: Option<u64>, | ||
| compressed_size: Option<u64>, | ||
| header_start: Option<u64>, | ||
| // Not used field | ||
| // disk_start: Option<u32> | ||
| } | ||
|
|
||
| impl Zip64ExtendedInformation { | ||
| const MAGIC: UsedExtraField = UsedExtraField::Zip64ExtendedInfo; | ||
|
|
||
| pub(crate) fn new_local(is_large_file: bool) -> Option<Self> { | ||
| if is_large_file { | ||
| Self::local_header(true, u64::MAX, u64::MAX) | ||
| } else { | ||
| None | ||
| } | ||
| } | ||
|
|
||
| /// This entry in the Local header MUST include BOTH original and compressed file size fields | ||
| /// If the user is using `is_large_file` when the file is not large we force the zip64 extra field | ||
| pub(crate) fn local_header( | ||
| is_large_file: bool, | ||
| uncompressed_size: u64, | ||
| compressed_size: u64, | ||
| ) -> Option<Self> { | ||
| // here - we force if `is_large_file` is `true` | ||
| let should_add_size = is_large_file | ||
| || uncompressed_size >= ZIP64_BYTES_THR | ||
| || compressed_size >= ZIP64_BYTES_THR; | ||
| if !should_add_size { | ||
| return None; | ||
| } | ||
| let size = (mem::size_of::<u64>() + mem::size_of::<u64>()) as u16; | ||
| let uncompressed_size = Some(uncompressed_size); | ||
| let compressed_size = Some(compressed_size); | ||
|
|
||
| // TODO: (unsupported for now) | ||
| // Disk Start Number 4 bytes Number of the disk on which this file starts | ||
|
|
||
| Some(Self { | ||
| _is_local_header: true, | ||
| magic: Self::MAGIC, | ||
| size, | ||
| uncompressed_size, | ||
| compressed_size, | ||
| header_start: None, | ||
| }) | ||
| } | ||
|
|
||
| pub(crate) fn central_header( | ||
| uncompressed_size: u64, | ||
| compressed_size: u64, | ||
| header_start: u64, | ||
| ) -> Option<Self> { | ||
| let mut size: u16 = 0; | ||
| let uncompressed_size = if uncompressed_size != 0 && uncompressed_size >= ZIP64_BYTES_THR { | ||
| size += mem::size_of::<u64>() as u16; | ||
| Some(uncompressed_size) | ||
| } else { | ||
| None | ||
| }; | ||
| let compressed_size = if compressed_size != 0 && compressed_size >= ZIP64_BYTES_THR { | ||
| size += mem::size_of::<u64>() as u16; | ||
| Some(compressed_size) | ||
| } else { | ||
| None | ||
| }; | ||
| let header_start = if header_start != 0 && header_start >= ZIP64_BYTES_THR { | ||
| size += mem::size_of::<u64>() as u16; | ||
| Some(header_start) | ||
| } else { | ||
| None | ||
| }; | ||
| // TODO: (unsupported for now) | ||
|
||
| // Disk Start Number 4 bytes Number of the disk on which this file starts | ||
|
|
||
| if size == 0 { | ||
| // no info added, return early | ||
| return None; | ||
| } | ||
|
|
||
| Some(Self { | ||
| _is_local_header: false, | ||
| magic: Self::MAGIC, | ||
| size, | ||
| uncompressed_size, | ||
| compressed_size, | ||
| header_start, | ||
| }) | ||
| } | ||
|
|
||
| /// Get the full size of the block | ||
| pub(crate) fn full_size(&self) -> usize { | ||
| self.size as usize + mem::size_of::<UsedExtraField>() + mem::size_of::<u16>() | ||
| } | ||
|
|
||
| /// Serialize the block | ||
| pub fn serialize(self) -> Box<[u8]> { | ||
| let Self { | ||
| _is_local_header, | ||
| magic, | ||
| size, | ||
| uncompressed_size, | ||
| compressed_size, | ||
| header_start, | ||
| } = self; | ||
|
|
||
| let full_size = self.full_size(); | ||
| if _is_local_header { | ||
| // the local header does not contains the header start | ||
| if let (Some(uncompressed_size), Some(compressed_size)) = | ||
| (self.compressed_size, self.compressed_size) | ||
| { | ||
| let mut ret = Vec::with_capacity(full_size); | ||
| ret.extend(magic.to_le_bytes()); | ||
| ret.extend(size.to_le_bytes()); | ||
| ret.extend(u64::to_le_bytes(uncompressed_size)); | ||
| ret.extend(u64::to_le_bytes(compressed_size)); | ||
| return ret.into_boxed_slice(); | ||
| } | ||
| // this should be unreachable | ||
| Box::new([]) | ||
| } else { | ||
| let mut ret = Vec::with_capacity(full_size); | ||
| ret.extend(magic.to_le_bytes()); | ||
| ret.extend(u16::to_le_bytes(size)); | ||
|
|
||
| if let Some(uncompressed_size) = uncompressed_size { | ||
| ret.extend(u64::to_le_bytes(uncompressed_size)); | ||
| } | ||
| if let Some(compressed_size) = compressed_size { | ||
| ret.extend(u64::to_le_bytes(compressed_size)); | ||
| } | ||
| if let Some(header_start) = header_start { | ||
| ret.extend(u64::to_le_bytes(header_start)); | ||
| } | ||
| debug_assert_eq!(ret.len(), full_size); | ||
|
|
||
| ret.into_boxed_slice() | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Check notice
Code scanning / devskim
A "TODO" or similar was left in source code, possibly indicating incomplete functionality Note