-
Notifications
You must be signed in to change notification settings - Fork 106
refactor: move types to zip format folder #827
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
Open
Its-Just-Nans
wants to merge
8
commits into
master
Choose a base branch
from
refactor-zip-format
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 3 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
ab0c5ca
refactor: move to format directory
Its-Just-Nans 7959d14
fix some docs
Its-Just-Nans 937d541
cargo fmrt
Its-Just-Nans 223f692
Remove unused import
Pr0methean 82a9073
cargo fmt --all
Pr0methean e49914b
Add missing import
Pr0methean d7a0a67
Change write to write_all in 2 tests
Pr0methean bb64084
fix: details
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| //! AES related specifications | ||
|
|
||
| use core::fmt::Display; | ||
|
|
||
| /// The encryption specification used to encrypt a file with AES. | ||
| /// | ||
| /// According to the [specification](https://www.winzip.com/win/en/aes_info.html#winzip11) AE-2 | ||
| /// does not make use of the CRC check. | ||
| #[derive(Copy, Clone, Debug, Eq, PartialEq)] | ||
| #[repr(u16)] | ||
| pub enum AesVendorVersion { | ||
| Ae1 = 0x0001, | ||
| Ae2 = 0x0002, | ||
| } | ||
|
|
||
| impl AesVendorVersion { | ||
| /// As u16 | ||
| #[must_use] | ||
| pub const fn as_u16(self) -> u16 { | ||
| self as u16 | ||
| } | ||
|
|
||
| /// Returns `true` if the data is encrypted using AE2. | ||
| #[cfg(feature = "aes-crypto")] | ||
| pub const fn is_ae2_encrypted(&self) -> bool { | ||
| matches!(self, AesVendorVersion::Ae2) | ||
| } | ||
|
|
||
| /// `false` since the feature `aes-crypto` is not enabled | ||
| #[cfg(not(feature = "aes-crypto"))] | ||
| pub const fn is_ae2_encrypted(&self) -> bool { | ||
| false | ||
| } | ||
| } | ||
|
|
||
| impl TryFrom<u16> for AesVendorVersion { | ||
|
Its-Just-Nans marked this conversation as resolved.
|
||
| type Error = &'static str; | ||
|
|
||
| fn try_from(value: u16) -> Result<Self, Self::Error> { | ||
| let aes_vendor_version = match value { | ||
| 0x0001 => AesVendorVersion::Ae1, | ||
| 0x0002 => AesVendorVersion::Ae2, | ||
| _ => return Err("Invalid AES vendor version"), | ||
| }; | ||
| Ok(aes_vendor_version) | ||
| } | ||
| } | ||
|
|
||
| impl From<AesVendorVersion> for u16 { | ||
| fn from(value: AesVendorVersion) -> Self { | ||
| value as u16 | ||
| } | ||
| } | ||
|
|
||
| /// AES variant used. | ||
| #[derive(Copy, Clone, Debug, Eq, PartialEq)] | ||
| #[cfg_attr(feature = "_arbitrary", derive(arbitrary::Arbitrary))] | ||
| #[repr(u8)] | ||
| pub enum AesMode { | ||
| /// 128-bit AES encryption. | ||
| Aes128 = 0x01, | ||
| /// 192-bit AES encryption. | ||
| Aes192 = 0x02, | ||
| /// 256-bit AES encryption. | ||
| Aes256 = 0x03, | ||
| } | ||
|
|
||
| impl AesMode { | ||
| /// As u8 | ||
| #[must_use] | ||
| pub const fn as_u8(self) -> u8 { | ||
| self as u8 | ||
| } | ||
| } | ||
|
|
||
| impl Display for AesMode { | ||
| fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | ||
| match self { | ||
| Self::Aes128 => write!(f, "AES-128"), | ||
| Self::Aes192 => write!(f, "AES-192"), | ||
| Self::Aes256 => write!(f, "AES-256"), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl TryFrom<u8> for AesMode { | ||
| type Error = &'static str; | ||
|
|
||
| fn try_from(value: u8) -> Result<Self, Self::Error> { | ||
| let mode = match value { | ||
| 0x01 => AesMode::Aes128, | ||
| 0x02 => AesMode::Aes192, | ||
| 0x03 => AesMode::Aes256, | ||
| _ => return Err("Invalid AES encryption strength"), | ||
| }; | ||
| Ok(mode) | ||
| } | ||
| } | ||
|
|
||
| #[cfg(feature = "aes-crypto")] | ||
| impl AesMode { | ||
| /// Length of the salt for the given AES mode. | ||
| #[must_use] | ||
| pub const fn salt_length(&self) -> usize { | ||
| self.key_length() / 2 | ||
| } | ||
|
|
||
| /// Length of the key for the given AES mode. | ||
| #[must_use] | ||
| pub const fn key_length(&self) -> usize { | ||
| match self { | ||
| Self::Aes128 => 16, | ||
| Self::Aes192 => 24, | ||
| Self::Aes256 => 32, | ||
| } | ||
| } | ||
| } | ||
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,160 @@ | ||
| //! Flags of zip | ||
|
|
||
| /// System inside `version made by` (upper byte) | ||
| /// Reference: 4.4.2.2 | ||
| #[derive(Clone, Copy, Debug, PartialEq, Eq, Default)] | ||
| #[allow(clippy::upper_case_acronyms)] | ||
| #[repr(u8)] | ||
| pub enum System { | ||
| /// `MS-DOS` and `OS/2` (`FAT` / `VFAT` / `FAT32` file systems; default on Windows) | ||
| Dos = 0, | ||
| /// `Amiga` | ||
| Amiga = 1, | ||
| /// `OpenVMS` | ||
| OpenVMS = 2, | ||
| /// Default on Unix; default for symlinks on all platforms | ||
| Unix = 3, | ||
| /// `VM/CMS` | ||
| VmCms = 4, | ||
| /// `Atari ST` | ||
| AtariSt = 5, | ||
| /// `OS/2 H.P.F.S.` | ||
| Os2 = 6, | ||
| /// Legacy `Mac OS`, pre `OS X` | ||
| Macintosh = 7, | ||
| /// `Z-System` | ||
| ZSystem = 8, | ||
| /// `CP/M` | ||
| CPM = 9, | ||
| /// Windows NTFS (with extra attributes; not used by default) | ||
| WindowsNTFS = 10, | ||
| /// `MVS (OS/390 - Z/OS)` | ||
| MVS = 11, | ||
| /// `VSE` | ||
| VSE = 12, | ||
| /// `Acorn Risc` | ||
| AcornRisc = 13, | ||
| /// `VFAT` | ||
| VFAT = 14, | ||
| /// alternate MVS | ||
| AlternateMVS = 15, | ||
| /// `BeOS` | ||
| BeOS = 16, | ||
| /// `Tandem` | ||
| Tandem = 17, | ||
| /// `OS/400` | ||
| Os400 = 18, | ||
| /// `OS X` (Darwin) (with extra attributes; not used by default) | ||
| OsDarwin = 19, | ||
| /// unused | ||
| #[default] | ||
| Unknown = 255, | ||
| } | ||
|
|
||
| impl System { | ||
| /// Parse `version_made_by` block in local entry block. | ||
| #[must_use] | ||
| pub fn from_version_made_by(version_made_by: u16) -> Self { | ||
| // Extract upper byte from little-endian representation | ||
| let upper_byte = version_made_by.to_le_bytes()[1]; | ||
| System::from(upper_byte) // from u8 | ||
| } | ||
|
|
||
| /// Extract the system and version from a `version_made_by` field. | ||
| /// The first byte (lower) is the version, and the second byte (upper) is the system. | ||
| pub(crate) fn extract_bytes(version_made_by: u16) -> (u8, Self) { | ||
| let bytes = version_made_by.to_le_bytes(); | ||
| (bytes[0], Self::from(bytes[1])) | ||
| } | ||
| } | ||
|
|
||
| impl From<u8> for System { | ||
| fn from(system: u8) -> Self { | ||
| match system { | ||
| 0 => System::Dos, | ||
| 1 => System::Amiga, | ||
| 2 => System::OpenVMS, | ||
| 3 => System::Unix, | ||
| 4 => System::VmCms, | ||
| 5 => System::AtariSt, | ||
| 6 => System::Os2, | ||
| 7 => System::Macintosh, | ||
| 8 => System::ZSystem, | ||
| 9 => System::CPM, | ||
| 10 => System::WindowsNTFS, | ||
| 11 => System::MVS, | ||
| 12 => System::VSE, | ||
| 13 => System::AcornRisc, | ||
| 14 => System::VFAT, | ||
| 15 => System::AlternateMVS, | ||
| 16 => System::BeOS, | ||
| 17 => System::Tandem, | ||
| 18 => System::Os400, | ||
| 19 => System::OsDarwin, | ||
| _ => System::Unknown, | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl From<System> for u8 { | ||
| fn from(system: System) -> Self { | ||
| system as u8 | ||
| } | ||
| } | ||
|
|
||
| /// Zip flags | ||
| /// Stored as Little endian | ||
| #[allow(unused)] | ||
|
Its-Just-Nans marked this conversation as resolved.
Outdated
|
||
| #[rustfmt::skip] | ||
| #[repr(u16)] | ||
| #[derive(Debug, Copy, Clone, PartialEq, Eq)] | ||
| #[non_exhaustive] | ||
| pub(crate) enum ZipFlags { | ||
| /// If set, indicates that the file is encrypted. | ||
| Encrypted = 0b0000_0000_0000_0001, | ||
| CompressionSetting = 0b0000_0000_0000_0010, | ||
| CompressionSetting2 = 0b0000_0000_0000_0100, | ||
| /// If this bit is set, the fields crc-32, compressed size and uncompressed size are set to zero in the local header. | ||
| /// The correct values are put in the data descriptor immediately following the compressed data. | ||
| UsingDataDescriptor = 0b0000_0000_0000_1000, | ||
| /// Reserved for use with method 8, for enhanced deflating. | ||
| ReservedEnhancedDeflating = 0b0000_0000_0001_0000, | ||
| /// If this bit is set, this indicates that the file is compressed patched data. | ||
| CompressedPatchedData = 0b0000_0000_0010_0000, | ||
| /// Strong encryption. | ||
| /// If this bit is set, you MUST set the version needed to extract value to at least 50 and you MUST also set bit 0. | ||
| /// If AES encryption is used, the version needed to extract value MUST be at least 51. | ||
| StrongEncryption = 0b0000_0000_0100_0000, | ||
| // bit 7 Currently unused = 0b0000_0000_1000_0000; | ||
| // bit 8 Currently unused = 0b0000_0001_0000_0000; | ||
| // bit 9 Currently unused = 0b0000_0010_0000_0000; | ||
| // bit 10 Currently unused = 0b0000_0100_0000_0000; | ||
|
|
||
| /// Language encoding flag (EFS). | ||
| /// If this bit is set, the filename and comment fields for this file MUST be encoded using UTF-8. | ||
| LanguageEncoding = 0b0000_1000_0000_0000, | ||
| /// Reserved by PKWARE for enhanced compression. | ||
| ReservedEnhancedCompression = 0b0001_0000_0000_0000, | ||
| /// Set when encrypting the Central Directory to indicate selected data values in the Local Header are masked to hide their actual values. | ||
| Masked = 0b0010_0000_0000_0000, | ||
| /// Reserved by PKWARE for alternate streams. | ||
| ReservedAlternateStream = 0b0100_0000_0000_0000, | ||
| /// Reserved by PKWARE. | ||
| Reserved = 0b1000_0000_0000_0000, | ||
| } | ||
|
|
||
| impl ZipFlags { | ||
| pub(crate) fn matching(flags: u16, matching_flag: Self) -> bool { | ||
| flags & u16::from(matching_flag) != 0 | ||
| } | ||
|
|
||
| pub(crate) const fn as_u16(self) -> u16 { | ||
| self as u16 | ||
| } | ||
| } | ||
|
|
||
| impl From<ZipFlags> for u16 { | ||
| fn from(value: ZipFlags) -> u16 { | ||
| value.as_u16() | ||
| } | ||
| } | ||
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,4 @@ | ||
| //! Zip format | ||
|
|
||
| pub(crate) mod aes; | ||
| pub(crate) mod flags; |
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
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.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method seems unnecessary. Can't it be either inlined or replaced with the
From<AesVendorVersion> for u16impl below?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am now using
as_u16()inside the FromUh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just use
as u16inside the From and wherever else it's currently used, so AesVendorVersion can have one less method?