Skip to content

Commit 8b8c20f

Browse files
Its-Just-Nansamazon-q-developer[bot]Pr0methean
authored
feat: document zip flags as enum (#639)
* feat: document flags as enum The best approach would be to use bitflags but it would be a breaking change * Update src/types.rs Co-authored-by: amazon-q-developer[bot] <208079219+amazon-q-developer[bot]@users.noreply.github.com> Signed-off-by: n4n5 <git@n4n5.dev> * Update src/spec.rs Co-authored-by: amazon-q-developer[bot] <208079219+amazon-q-developer[bot]@users.noreply.github.com> Signed-off-by: n4n5 <git@n4n5.dev> * rename * cargo fmt --all --------- Signed-off-by: n4n5 <git@n4n5.dev> Signed-off-by: Chris Hennick <4961925+Pr0methean@users.noreply.github.com> Co-authored-by: amazon-q-developer[bot] <208079219+amazon-q-developer[bot]@users.noreply.github.com> Co-authored-by: Chris Hennick <4961925+Pr0methean@users.noreply.github.com>
1 parent 08d7578 commit 8b8c20f

5 files changed

Lines changed: 65 additions & 26 deletions

File tree

src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,10 @@
3737
clippy::missing_panics_doc,
3838
clippy::cargo,
3939
clippy::panic,
40-
clippy::cast_lossless
40+
clippy::cast_lossless,
41+
clippy::decimal_literal_representation
4142
)]
43+
#![warn(clippy::multiple_crate_versions)]
4244
#![cfg_attr(not(test), deny(clippy::unwrap_used, clippy::expect_used))]
4345
#![allow(unexpected_cfgs)] // Needed for cfg(fuzzing)
4446
pub use crate::compression::{CompressionMethod, SUPPORTED_COMPRESSION_METHODS};

src/read.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::crc32::Crc32Reader;
77
use crate::extra_fields::{ExtendedTimestamp, ExtraField, Ntfs, UsedExtraField};
88
use crate::result::{ZipError, ZipResult, invalid};
99
use crate::spec::{
10-
self, CentralDirectoryEndInfo, DataAndPosition, FixedSizeBlock, Pod, ZIP64_BYTES_THR,
10+
self, CentralDirectoryEndInfo, DataAndPosition, FixedSizeBlock, Pod, ZIP64_BYTES_THR, ZipFlags,
1111
};
1212
use crate::types::{
1313
AesMode, AesVendorVersion, DateTime, SimpleFileOptions, System, ZipCentralEntryBlock,
@@ -1450,9 +1450,9 @@ fn central_header_to_zip_file_inner<R: Read>(
14501450
..
14511451
} = block;
14521452

1453-
let encrypted = flags & 1 == 1;
1454-
let is_utf8 = flags & (1 << 11) != 0;
1455-
let using_data_descriptor = flags & (1 << 3) != 0;
1453+
let encrypted = flags & (ZipFlags::Encrypted as u16) != 0;
1454+
let is_utf8 = flags & (ZipFlags::LanguageEncoding as u16) != 0;
1455+
let using_data_descriptor = flags & (ZipFlags::UsingDataDescriptor as u16) != 0;
14561456

14571457
let file_name_raw = read_variable_length_byte_field(reader, file_name_length as usize)?;
14581458
let extra_field = read_variable_length_byte_field(reader, extra_field_length as usize)?;

src/spec.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,46 @@ impl Magic {
5353
pub const DATA_DESCRIPTOR_SIGNATURE: Self = Self::literal(0x08074b50);
5454
}
5555

56+
/// Zip flags
57+
/// Stored as Little endian
58+
#[allow(unused)]
59+
#[rustfmt::skip]
60+
#[repr(u16)]
61+
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
62+
pub(crate) enum ZipFlags {
63+
/// If set, indicates that the file is encrypted.
64+
Encrypted = 0b0000_0000_0000_0001,
65+
CompressionSetting = 0b0000_0000_0000_0010,
66+
CompressionSetting2 = 0b0000_0000_0000_0100,
67+
/// If this bit is set, the fields crc-32, compressed size and uncompressed size are set to zero in the local header.
68+
/// The correct values are put in the data descriptor immediately following the compressed data.
69+
UsingDataDescriptor = 0b0000_0000_0000_1000,
70+
/// Reserved for use with method 8, for enhanced deflating.
71+
ReservedEnhancedDeflating = 0b0000_0000_0001_0000,
72+
/// If this bit is set, this indicates that the file is compressed patched data.
73+
CompressedPatchedData = 0b0000_0000_0010_0000,
74+
/// Strong encryption.
75+
/// 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.
76+
/// If AES encryption is used, the version needed to extract value MUST be at least 51.
77+
StrongEncryption = 0b0000_0000_0100_0000,
78+
// bit 7 Currently unused = 0b0000_0000_1000_0000;
79+
// bit 8 Currently unused = 0b0000_0001_0000_0000;
80+
// bit 9 Currently unused = 0b0000_0010_0000_0000;
81+
// bit 10 Currently unused = 0b0000_0100_0000_0000;
82+
83+
/// Language encoding flag (EFS).
84+
/// If this bit is set, the filename and comment fields for this file MUST be encoded using UTF-8.
85+
LanguageEncoding = 0b0000_1000_0000_0000,
86+
/// Reserved by PKWARE for enhanced compression.
87+
ReservedEnhancedCompression = 0b0001_0000_0000_0000,
88+
/// Set when encrypting the Central Directory to indicate selected data values in the Local Header are masked to hide their actual values.
89+
Masked = 0b0010_0000_0000_0000,
90+
/// Reserved by PKWARE for alternate streams.
91+
ReservedAlternateStream = 0b0100_0000_0000_0000,
92+
/// Reserved by PKWARE.
93+
Reserved = 0b1000_0000_0000_0000,
94+
}
95+
5696
/// Similar to [`Magic`], but used for extra field tags as per section 4.5.3 of APPNOTE.TXT.
5797
#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq, Hash)]
5898
#[repr(transparent)]

src/types.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
//! Types that specify what is contained in a ZIP.
22
use crate::cfg_if_expr;
33
use crate::cp437::FromCp437;
4+
use crate::result::{ZipError, ZipResult, invalid};
5+
use crate::spec::{self, FixedSizeBlock, Pod, ZipFlags};
46
use crate::write::FileOptionExtension;
57
use crate::zipcrypto::EncryptWith;
68
use core::fmt::{self, Debug, Formatter};
@@ -10,9 +12,6 @@ use std::path::{Path, PathBuf};
1012
use std::sync::{Arc, OnceLock};
1113
use typed_path::{Utf8WindowsComponent, Utf8WindowsPath};
1214

13-
use crate::result::{ZipError, ZipResult, invalid};
14-
use crate::spec::{self, FixedSizeBlock, Pod};
15-
1615
pub(crate) mod ffi {
1716
pub const S_IFDIR: u32 = 0o0040000;
1817
pub const S_IFREG: u32 = 0o0100000;
@@ -781,24 +780,22 @@ impl ZipFileData {
781780
..
782781
} = block;
783782

784-
let encrypted: bool = flags & 1 == 1;
783+
let encrypted: bool = flags & (ZipFlags::Encrypted as u16) != 0;
785784
if encrypted {
786785
return Err(ZipError::UnsupportedArchive(
787786
"Encrypted files are not supported",
788787
));
789788
}
790789

791790
/* FIXME: these were previously incorrect: add testing! */
792-
/* flags & (1 << 3) != 0 */
793-
let using_data_descriptor: bool = flags & (1 << 3) == 1 << 3;
791+
let using_data_descriptor: bool = flags & (ZipFlags::UsingDataDescriptor as u16) != 0;
794792
if using_data_descriptor {
795793
return Err(ZipError::UnsupportedArchive(
796794
"The file length is not available in the local header",
797795
));
798796
}
799797

800-
/* flags & (1 << 1) != 0 */
801-
let is_utf8: bool = flags & (1 << 11) != 0;
798+
let is_utf8: bool = flags & (ZipFlags::LanguageEncoding as u16) != 0;
802799
let compression_method = crate::CompressionMethod::parse_from_u16(compression_method);
803800
let file_name_length: usize = file_name_length.into();
804801
let extra_field_length: usize = extra_field_length.into();
@@ -876,13 +873,13 @@ impl ZipFileData {
876873

877874
fn flags(&self) -> u16 {
878875
let utf8_bit: u16 = if self.is_utf8() && !self.is_ascii() {
879-
1u16 << 11
876+
ZipFlags::LanguageEncoding as u16
880877
} else {
881878
0
882879
};
883880

884881
let using_data_descriptor_bit = if self.using_data_descriptor {
885-
1u16 << 3
882+
ZipFlags::UsingDataDescriptor as u16
886883
} else {
887884
0
888885
};

src/write.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2928,7 +2928,7 @@ mod test {
29282928
fn remove_encrypted_file() -> ZipResult<()> {
29292929
let mut writer = ZipWriter::new(Cursor::new(Vec::new()));
29302930
let first_file_options = SimpleFileOptions::default()
2931-
.with_alignment(65535)
2931+
.with_alignment(0xFFFF)
29322932
.with_deprecated_encryption(b"Password");
29332933
writer.start_file("", first_file_options).unwrap();
29342934
writer.abort_file().unwrap();
@@ -2942,7 +2942,7 @@ mod test {
29422942
fn remove_encrypted_aligned_symlink() -> ZipResult<()> {
29432943
let mut options = SimpleFileOptions::default();
29442944
options = options.with_deprecated_encryption(b"Password");
2945-
options.alignment = 65535;
2945+
options.alignment = 0xFFFF;
29462946
let mut writer = ZipWriter::new(Cursor::new(Vec::new()));
29472947
writer.add_symlink("", "s\t\0\0ggggg\0\0", options).unwrap();
29482948
writer.abort_file().unwrap();
@@ -3318,14 +3318,14 @@ mod test {
33183318
central_extra_data: vec![].into(),
33193319
file_comment: None,
33203320
},
3321-
alignment: 65521,
3321+
alignment: 0xFFF1,
33223322
..Default::default()
33233323
};
33243324
writer.start_file_from_path("\u{4}\0@\n//\u{c}", options)?;
33253325
writer = ZipWriter::new_append(writer.finish()?)?;
33263326
writer.abort_file()?;
33273327
let options = FileOptions {
3328-
compression_method: CompressionMethod::Unsupported(65535),
3328+
compression_method: CompressionMethod::Unsupported(0xFFFF),
33293329
compression_level: None,
33303330
last_modified_time: DateTime::from_date_and_time(2055, 10, 2, 11, 48, 49)?,
33313331
permissions: None,
@@ -3336,7 +3336,7 @@ mod test {
33363336
central_extra_data: vec![].into(),
33373337
file_comment: None,
33383338
},
3339-
alignment: 65535,
3339+
alignment: 0xFFFF,
33403340
..Default::default()
33413341
};
33423342
writer.add_directory_from_path("", options)?;
@@ -3405,7 +3405,7 @@ mod test {
34053405
.into(),
34063406
file_comment: None,
34073407
},
3408-
alignment: 65535,
3408+
alignment: 0xFFFF,
34093409
..Default::default()
34103410
};
34113411
assert!(writer.add_directory_from_path("", options).is_err());
@@ -3432,7 +3432,7 @@ mod test {
34323432
.into(),
34333433
file_comment: None,
34343434
},
3435-
alignment: 65535,
3435+
alignment: 0xFFFF,
34363436
..Default::default()
34373437
};
34383438
assert!(writer.add_directory_from_path("", options).is_err());
@@ -3475,7 +3475,7 @@ mod test {
34753475
writer.set_flush_on_finish_file(false);
34763476
let options = FileOptions {
34773477
compression_method: CompressionMethod::Unsupported(
3478-
65535,
3478+
0xFFFF,
34793479
),
34803480
compression_level: Some(5),
34813481
last_modified_time: DateTime::from_date_and_time(
@@ -3569,7 +3569,7 @@ mod test {
35693569
central_extra_data: vec![].into(),
35703570
file_comment: None,
35713571
},
3572-
alignment: 65535,
3572+
alignment: 0xFFFF,
35733573
..Default::default()
35743574
};
35753575
writer.add_symlink_from_path("", "\nu", options)?;
@@ -4056,7 +4056,7 @@ mod test {
40564056
central_extra_data: vec![].into(),
40574057
file_comment: None,
40584058
},
4059-
alignment: 65535,
4059+
alignment: 0xFFFF,
40604060
..Default::default()
40614061
};
40624062
writer.start_file_from_path("", options)?;
@@ -4115,7 +4115,7 @@ mod test {
41154115
central_extra_data: vec![].into(),
41164116
file_comment: None,
41174117
},
4118-
alignment: 65535,
4118+
alignment: 0xFFFF,
41194119
..Default::default()
41204120
};
41214121
writer.start_file_from_path("", options)?;

0 commit comments

Comments
 (0)