1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331
//! `zip-core::raw` contains 1:1 memory format of zip headers for use in your
//! projects e.g. if you want to build your own zip crate.
//!
//! Note: for concenience, all structs with variable size are split into a fixed
//! part and the variable part. The fixed part is prepended with `Fixed`. This
//! should make parsing easier
//!
//!
//! ### Rage List of things about <https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT>
//! - all fields unless noted are unsigned and little endian (there are no
//! notions), however we should set one to -1 in 4.4.1.4, how?!?!
//! - optional signature that are not standart but are recomended.
//! - noone explains what zip64 does, what it tries to do, etc.
//! - measurements, sometimes its offset, sometimes total size, sometimes
//! remaining size, and sometimes, size from this byte onwards
//!
//! #### Naming Rage
//! During reading the document I almost had a seizure regarding to naming.
//! Nevertheless I decided against renaming fields, as this is what the author
//! PKWARE decided on, and probably the whole industry has adopted to and i dont
//! want to create xkcd:927 However, if in future revisions some names are
//! adopted I would be more than happy. Here are some of the incompatibilities
//!
//! - of all fields and structures, sometimes sturct, sometimes record, often
//! nothing
//! - sometimes central dir, sometimes central directory
//! - Zip64 end of central directory locator vs Zip64 end of central directory
//! locator record
//! - the central directory is sometimes a single central directory header and
//! sometimes a central directory structure
//! - sometimes its a length sometimes a size
extern crate alloc;
use alloc::vec::Vec;
#[cfg(feature = "parse")] pub mod parse;
/// part of [`LocalFileHeader`] which has a fixed size
///
/// [`LocalFileHeader`]: LocalFileHeader
#[derive(Debug, PartialEq)]
pub struct LocalFileHeaderFixed {
pub local_file_header_signature: u32,
pub version_needed_to_extract: u16,
pub general_purpose_bit_flag: u16,
pub compression_method: u16,
pub last_mod_file_time: u16,
pub last_mod_file_date: u16,
pub crc_32: u32,
pub compressed_size: u32,
pub uncompressed_size: u32,
pub file_name_length: u16,
pub extra_field_length: u16,
}
/// Local File Header
///
/// The local file header is prepended before each file.
/// The bytes after it are usually the file or an Encryption Header.
/// is is linked by an [`CentralDirectoryHeader`]
///
/// see [4.3.7](https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT)
///
/// [`CentralDirectoryHeader`]: CentralDirectoryHeader
#[derive(Debug, PartialEq)]
pub struct LocalFileHeader {
pub fixed: LocalFileHeaderFixed,
pub file_name: Vec<u8>,
pub extra_field: Vec<u8>,
}
/// Data descriptor
///
/// the data descriptior is prepended to the file data.
/// It might be used sometimes, in this case the corresponding fields in
/// [`LocalFileHeader`] are zero.
///
/// Note: There exists a zip64 variant of this descriptor:
/// [`DataDescriptorZip64`] Note: the DataDescriptor should contain a signature,
/// see the struct [`DataDescriptorSignature`]. Its not standart but recomended.
/// When parsing you are on your own if the first 4 bytes a the signature or
/// just a random crc32 according to the documentation
/// see [`DataDescriptorZip64Signature`] for Zip64 with Signature
///
/// see [4.3.9](https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT)
///
/// [`LocalFileHeader`]: LocalFileHeaderFixed
/// [`DataDescriptorZip64`]: DataDescriptorZip64
/// [`DataDescriptorSignature`]: DataDescriptorSignature
/// [`DataDescriptorZip64Signature`]: DataDescriptorZip64Signature
#[derive(Debug, PartialEq)]
pub struct DataDescriptor {
pub crc_32: u32,
pub compressed_size: u32,
pub uncompressed_size: u32,
}
/// Data descriptor with a signature see [`DataDescriptor`]
///
/// [`DataDescriptor`]: DataDescriptor
#[derive(Debug, PartialEq)]
pub struct DataDescriptorSignature {
pub signature: u32,
pub crc_32: u32,
pub compressed_size: u32,
pub uncompressed_size: u32,
}
/// Data descriptor for Zip64, sizes are 8 bytes instead of 4, see
/// [`DataDescriptor`]
///
/// [`DataDescriptor`]: DataDescriptor
#[derive(Debug, PartialEq)]
pub struct DataDescriptorZip64 {
pub crc_32: u32,
pub compressed_size: u64,
pub uncompressed_size: u64,
}
/// Data descriptor for Zip64, sizes are 8 bytes instead of 4 and with a
/// signature, see [`DataDescriptor`]
///
/// [`DataDescriptor`]: DataDescriptor
#[derive(Debug, PartialEq)]
pub struct DataDescriptorZip64Signature {
pub signature: u32,
pub crc_32: u32,
pub compressed_size: u64,
pub uncompressed_size: u64,
}
/// part of [`ArchiveExtraDataRecord`] which has a fixed size
///
/// [`ArchiveExtraDataRecord`]: ArchiveExtraDataRecord
#[derive(Debug, PartialEq)]
pub struct ArchiveExtraDataRecordFixed {
pub archive_extra_data_signature: u32,
pub extra_field_length: u64,
}
/// Archive Extra Data Record
///
/// May be used to support the Central Directory Encryption Feature
///
/// see [4.3.11](https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT)
#[derive(Debug, PartialEq)]
pub struct ArchiveExtraDataRecord {
pub fixed: ArchiveExtraDataRecordFixed,
pub extra_field_data: Vec<u8>,
}
/// part of [`CentralDirectoryHeader`] which has a fixed size
///
/// [`CentralDirectoryHeader`]: CentralDirectoryHeader
#[derive(Debug, PartialEq)]
pub struct CentralDirectoryHeaderFixed {
pub central_file_header_signature: u32,
pub version_made_by: u16,
pub version_needed_to_extract: u16,
pub general_purpose_bit_flag: u16,
pub compression_method: u16,
pub last_mod_file_time: u16,
pub last_mod_file_date: u16,
pub crc_32: u32,
pub compressed_size: u32,
pub uncompressed_size: u32,
pub file_name_length: u16,
pub extra_field_length: u16,
pub file_comment_length: u16,
pub disk_number_start: u16,
pub internal_file_attributes: u16,
pub external_file_attributes: u32,
pub relative_offset_of_local_header: u32,
}
/// Central Directory Header
///
/// The Central Directory Structure contains of multiple Central Directory
/// Headers and a Digital Signature. Note: the documentation is confusing about
/// this, the Digital Signature is left out in `4.3.6` and Archive Decryption
/// Header and [`ArchiveExtraDataRecord`] seem to be not part of it, though they
/// have a strong dependency.
///
/// Each Central Directory Header links to exactly one [`LocalFileHeader`]
///
/// see [4.3.12](https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT)
///
/// [`ArchiveExtraDataRecord`]: ArchiveExtraDataRecord
/// [`LocalFileHeader`]: LocalFileHeader
#[derive(Debug, PartialEq)]
pub struct CentralDirectoryHeader {
pub fixed: CentralDirectoryHeaderFixed,
pub file_name: Vec<u8>,
pub extra_field: Vec<u8>,
pub file_comment: Vec<u8>,
}
/// part of [`DigitalSignature`] which has a fixed size
///
/// [`DigitalSignature`]: DigitalSignature
#[derive(Debug, PartialEq)]
pub struct DigitalSignatureFixed {
pub header_signature: u32,
pub size_of_data: u16,
}
/// part of [`LocalFileHeader`] which has a fixed size
///
/// [`LocalFileHeader`]: LocalFileHeader
#[derive(Debug, PartialEq)]
pub struct DigitalSignature {
pub fixed: DigitalSignatureFixed,
pub signature_data: Vec<u8>,
}
/// Zip64 end of central directory record
///
/// see [4.3.14](https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT)
#[derive(Debug, PartialEq)]
pub struct Zip64EndOfCentralDirectoryFixed {
pub zip64_end_of_central_dir_signature: u32,
pub size_of_zip64_end_of_central_directory_record: u64,
pub version_made_by: u16,
pub version_needed_to_extract: u16,
pub number_of_this_disk: u32,
pub number_of_the_disk_with_the_start_of_the_central_directory: u32,
pub total_number_of_entries_in_the_central_directory_on_this_disk: u64,
pub total_number_of_entries_in_the_central_directory: u64,
pub size_of_the_central_directory: u64,
pub offset_of_start_of_central_directory_with_respect_to_the_starting_disk_number: u64,
}
/// part of [`Zip64EndOfCentralDirectory`] which has a fixed size
///
/// [`Zip64EndOfCentralDirectory`]: Zip64EndOfCentralDirectory
#[derive(Debug, PartialEq)]
pub struct Zip64EndOfCentralDirectory {
pub fixed: Zip64EndOfCentralDirectoryFixed,
pub zip64_extensible_data_sector: Vec<u8>,
}
/// Zip64 end of central directory locator
///
/// see [4.3.14](https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT)
#[derive(Debug, PartialEq)]
pub struct Zip64EndOfCentralDirectoryLocator {
pub zip64_end_of_central_dir_locator_signature: u32,
pub number_of_the_disk_with_the_start_of_the_central_directory: u32,
pub relative_offset_of_the_zip64_end_of_central_directory_record: u64,
pub number_of_this_disk: u32,
}
/// part of [`EndOfCentralDirectory`] which has a fixed size
///
/// [`EndOfCentralDirectory`]: EndOfCentralDirectory
#[derive(Debug, PartialEq)]
pub struct EndOfCentralDirectoryFixed {
pub end_of_central_dir_signature: u32,
pub number_of_this_disk: u16,
pub number_of_the_disk_with_the_start_of_the_central_directory: u16,
pub total_number_of_entries_in_the_central_directory_on_this_disk: u16,
pub total_number_of_entries_in_the_central_directory: u16,
pub size_of_the_central_directory: u32,
pub offset_of_start_of_central_directory_with_respect_to_the_starting_disk_number: u32,
pub zip_file_comment_length: u16,
}
/// End of central directory record
///
/// see [4.3.16](https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT)
#[derive(Debug, PartialEq)]
pub struct EndOfCentralDirectory {
pub fixed: EndOfCentralDirectoryFixed,
pub zip_file_comment: Vec<u8>,
}
impl LocalFileHeaderFixed {
pub const LOCAL_FILE_HEADER_SIGNATURE: u32 = 0x04034b50;
pub const SIZE_IN_BYTES: usize = 30;
}
impl DataDescriptor {
/// Note: At time of writing this is an optional, de-facto-standart
/// signature
pub const SIGNATURE: u32 = 0x08074b50;
pub const SIZE_IN_BYTES: usize = 12;
}
impl DataDescriptorSignature {
pub const SIZE_IN_BYTES: usize = 16;
}
impl DataDescriptorZip64 {
pub const SIZE_IN_BYTES: usize = 20;
}
impl DataDescriptorZip64Signature {
pub const SIZE_IN_BYTES: usize = 24;
}
impl ArchiveExtraDataRecordFixed {
pub const SIZE_IN_BYTES: usize = 12;
}
impl ArchiveExtraDataRecordFixed {
pub const ARCHIVE_EXTRA_DATE_SIGNATURE: u32 = 0x08064b50;
}
impl CentralDirectoryHeaderFixed {
pub const CENTRAL_FILE_HEADER_SIGNATURE: u32 = 0x02014b50;
pub const SIZE_IN_BYTES: usize = 46;
}
impl DigitalSignatureFixed {
pub const HEADER_SIGNATURE: u32 = 0x05054b50;
pub const SIZE_IN_BYTES: usize = 6;
}
impl Zip64EndOfCentralDirectoryFixed {
pub const SIZE_IN_BYTES: usize = 56;
pub const ZIP64_END_OF_CENTRAL_DIR_SIGNATURE: u32 = 0x06064b50;
}
impl Zip64EndOfCentralDirectoryLocator {
pub const SIZE_IN_BYTES: usize = 20;
pub const ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE: u32 = 0x07064b50;
}
impl EndOfCentralDirectoryFixed {
pub const END_OF_CENTRAL_DIR_SIGNATURE: u32 = 0x06054b50;
pub const SIZE_IN_BYTES: usize = 22;
}