diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 3e25bed6..1e7b3953 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -16,7 +16,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macOS-latest, windows-latest] - rust: [stable] + rust: [stable, 1.34.0] steps: - uses: actions/checkout@master diff --git a/Cargo.toml b/Cargo.toml index 2fbb331d..9bdab53e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ edition = "2018" [dependencies] flate2 = { version = "1.0", default-features = false, optional = true } time = { version = "0.1", optional = true } -podio = "0.1" +byteorder = "1.3" bzip2 = { version = "0.3", optional = true } crc32fast = "1.0" thiserror = "1.0" diff --git a/README.md b/README.md index 8f4d219f..9a062c57 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,17 @@ The features available are: All of these are enabled by default. +MSRV +---- + +Our current Minimum Supported Rust Version is **1.34.0**. When adding features, +we will follow these guidelines: + +- We will always support the latest four minor Rust versions. This gives you a 6 + month window to upgrade your compiler. +- Any change to the MSRV will be accompanied with a **minor** version bump + - While the crate is pre-1.0, this will be a change to the PATCH version. + Examples -------- diff --git a/src/compression.rs b/src/compression.rs index 40916f94..5888fe7c 100644 --- a/src/compression.rs +++ b/src/compression.rs @@ -2,6 +2,7 @@ use std::fmt; +#[allow(deprecated)] /// Compression methods for the contents of a ZIP file. #[derive(Copy, Clone, PartialEq, Debug)] pub enum CompressionMethod { @@ -18,12 +19,21 @@ pub enum CompressionMethod { #[cfg(feature = "bzip2")] Bzip2, /// Unsupported compression method + #[deprecated( + since = "0.5.7", + note = "implementation details are being removed from the public API" + )] Unsupported(u16), } impl CompressionMethod { /// Converts an u16 to its corresponding CompressionMethod + #[deprecated( + since = "0.5.7", + note = "implementation details are being removed from the public API" + )] pub fn from_u16(val: u16) -> CompressionMethod { + #[allow(deprecated)] match val { 0 => CompressionMethod::Stored, #[cfg(any( @@ -34,12 +44,18 @@ impl CompressionMethod { 8 => CompressionMethod::Deflated, #[cfg(feature = "bzip2")] 12 => CompressionMethod::Bzip2, + v => CompressionMethod::Unsupported(v), } } /// Converts a CompressionMethod to a u16 + #[deprecated( + since = "0.5.7", + note = "implementation details are being removed from the public API" + )] pub fn to_u16(self) -> u16 { + #[allow(deprecated)] match self { CompressionMethod::Stored => 0, #[cfg(any( @@ -69,7 +85,9 @@ mod test { #[test] fn from_eq_to() { for v in 0..(::std::u16::MAX as u32 + 1) { + #[allow(deprecated)] let from = CompressionMethod::from_u16(v as u16); + #[allow(deprecated)] let to = from.to_u16() as u32; assert_eq!(v, to); } @@ -92,8 +110,11 @@ mod test { #[test] fn to_eq_from() { fn check_match(method: CompressionMethod) { + #[allow(deprecated)] let to = method.to_u16(); + #[allow(deprecated)] let from = CompressionMethod::from_u16(to); + #[allow(deprecated)] let back = from.to_u16(); assert_eq!(to, back); } diff --git a/src/read.rs b/src/read.rs index dfc80a17..e7dbe026 100644 --- a/src/read.rs +++ b/src/read.rs @@ -11,7 +11,7 @@ use std::io::prelude::*; use crate::cp437::FromCp437; use crate::types::{DateTime, System, ZipFileData}; -use podio::{LittleEndian, ReadPodExt}; +use byteorder::{LittleEndian, ReadBytesExt}; #[cfg(any( feature = "deflate", @@ -353,9 +353,12 @@ fn central_header_to_zip_file( let _internal_file_attributes = reader.read_u16::()?; let external_file_attributes = reader.read_u32::()?; let offset = reader.read_u32::()? as u64; - let file_name_raw = ReadPodExt::read_exact(reader, file_name_length)?; - let extra_field = ReadPodExt::read_exact(reader, extra_field_length)?; - let file_comment_raw = ReadPodExt::read_exact(reader, file_comment_length)?; + let mut file_name_raw = vec![0; file_name_length]; + reader.read_exact(&mut file_name_raw)?; + let mut extra_field = vec![0; extra_field_length]; + reader.read_exact(&mut extra_field)?; + let mut file_comment_raw = vec![0; file_comment_length]; + reader.read_exact(&mut file_comment_raw)?; let file_name = match is_utf8 { true => String::from_utf8_lossy(&*file_name_raw).into_owned(), @@ -371,7 +374,10 @@ fn central_header_to_zip_file( system: System::from_u8((version_made_by >> 8) as u8), version_made_by: version_made_by as u8, encrypted, - compression_method: CompressionMethod::from_u16(compression_method), + compression_method: { + #[allow(deprecated)] + CompressionMethod::from_u16(compression_method) + }, last_modified_time: DateTime::from_msdos(last_mod_date, last_mod_time), crc32, compressed_size: compressed_size as u64, @@ -632,6 +638,7 @@ pub fn read_zipfile_from_stream<'a, R: io::Read>( let encrypted = flags & 1 == 1; let is_utf8 = flags & (1 << 11) != 0; let using_data_descriptor = flags & (1 << 3) != 0; + #[allow(deprecated)] let compression_method = CompressionMethod::from_u16(reader.read_u16::()?); let last_mod_time = reader.read_u16::()?; let last_mod_date = reader.read_u16::()?; @@ -641,8 +648,10 @@ pub fn read_zipfile_from_stream<'a, R: io::Read>( let file_name_length = reader.read_u16::()? as usize; let extra_field_length = reader.read_u16::()? as usize; - let file_name_raw = ReadPodExt::read_exact(reader, file_name_length)?; - let extra_field = ReadPodExt::read_exact(reader, extra_field_length)?; + let mut file_name_raw = vec![0; file_name_length]; + reader.read_exact(&mut file_name_raw)?; + let mut extra_field = vec![0; extra_field_length]; + reader.read_exact(&mut extra_field)?; let file_name = match is_utf8 { true => String::from_utf8_lossy(&*file_name_raw).into_owned(), @@ -725,7 +734,7 @@ mod test { let mut v = Vec::new(); v.extend_from_slice(include_bytes!("../tests/data/mimetype.zip")); let reader = ZipArchive::new(io::Cursor::new(v)).unwrap(); - assert!(reader.comment() == b"zip-rs"); + assert!(reader.comment() == b""); } #[test] diff --git a/src/spec.rs b/src/spec.rs index c2ff907b..8fa8c5c1 100644 --- a/src/spec.rs +++ b/src/spec.rs @@ -1,5 +1,5 @@ use crate::result::{ZipError, ZipResult}; -use podio::{LittleEndian, ReadPodExt, WritePodExt}; +use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use std::io; use std::io::prelude::*; @@ -32,7 +32,8 @@ impl CentralDirectoryEnd { let central_directory_size = reader.read_u32::()?; let central_directory_offset = reader.read_u32::()?; let zip_file_comment_length = reader.read_u16::()? as usize; - let zip_file_comment = ReadPodExt::read_exact(reader, zip_file_comment_length)?; + let mut zip_file_comment = vec![0; zip_file_comment_length]; + reader.read_exact(&mut zip_file_comment)?; Ok(CentralDirectoryEnd { disk_number, diff --git a/src/types.rs b/src/types.rs index e23fab9b..a855c923 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,6 +1,5 @@ //! Types that specify what is contained in a ZIP. -#[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq)] pub enum System { Dos = 0, diff --git a/src/write.rs b/src/write.rs index f0d622ec..f5239298 100644 --- a/src/write.rs +++ b/src/write.rs @@ -4,8 +4,8 @@ use crate::compression::CompressionMethod; use crate::result::{ZipError, ZipResult}; use crate::spec; use crate::types::{DateTime, System, ZipFileData, DEFAULT_VERSION}; +use byteorder::{LittleEndian, WriteBytesExt}; use crc32fast::Hasher; -use podio::{LittleEndian, WritePodExt}; use std::default::Default; use std::io; use std::io::prelude::*; @@ -192,7 +192,7 @@ impl ZipWriter { files: Vec::new(), stats: Default::default(), writing_to_file: false, - comment: "zip-rs".into(), + comment: String::new(), } } @@ -417,23 +417,26 @@ impl GenericZipWriter { } }; - *self = match compression { - CompressionMethod::Stored => GenericZipWriter::Storer(bare), + *self = { + #[allow(deprecated)] + match compression { + CompressionMethod::Stored => GenericZipWriter::Storer(bare), #[cfg(any( feature = "deflate", feature = "deflate-miniz", feature = "deflate-zlib" ))] - CompressionMethod::Deflated => GenericZipWriter::Deflater(DeflateEncoder::new( - bare, - flate2::Compression::default(), - )), - #[cfg(feature = "bzip2")] - CompressionMethod::Bzip2 => { - GenericZipWriter::Bzip2(BzEncoder::new(bare, bzip2::Compression::Default)) - } - CompressionMethod::Unsupported(..) => { - return Err(ZipError::UnsupportedArchive("Unsupported compression")) + CompressionMethod::Deflated => GenericZipWriter::Deflater(DeflateEncoder::new( + bare, + flate2::Compression::default(), + )), + #[cfg(feature = "bzip2")] + CompressionMethod::Bzip2 => { + GenericZipWriter::Bzip2(BzEncoder::new(bare, bzip2::Compression::Default)) + } + CompressionMethod::Unsupported(..) => { + return Err(ZipError::UnsupportedArchive("Unsupported compression")) + } } }; @@ -505,6 +508,7 @@ fn write_local_file_header(writer: &mut T, file: &ZipFileData) -> ZipR }; writer.write_u16::(flag)?; // Compression method + #[allow(deprecated)] writer.write_u16::(file.compression_method.to_u16())?; // last mod file time and last mod file date writer.write_u16::(file.last_modified_time.timepart())?; @@ -556,6 +560,7 @@ fn write_central_directory_header(writer: &mut T, file: &ZipFileData) }; writer.write_u16::(flag)?; // compression method + #[allow(deprecated)] writer.write_u16::(file.compression_method.to_u16())?; // last mod file time + date writer.write_u16::(file.last_modified_time.timepart())?; @@ -645,7 +650,7 @@ mod test { .write(b"writing to a directory is not allowed, and will not write any data") .is_err()); let result = writer.finish().unwrap(); - assert_eq!(result.get_ref().len(), 114); + assert_eq!(result.get_ref().len(), 108); assert_eq!( *result.get_ref(), &[ @@ -653,7 +658,7 @@ mod test { 0, 0, 5, 0, 0, 0, 116, 101, 115, 116, 47, 80, 75, 1, 2, 46, 3, 20, 0, 0, 0, 0, 0, 163, 165, 15, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 65, 0, 0, 0, 0, 116, 101, 115, 116, 47, 80, 75, 5, 6, 0, 0, 0, 0, 1, 0, - 1, 0, 51, 0, 0, 0, 35, 0, 0, 0, 6, 0, 122, 105, 112, 45, 114, 115 + 1, 0, 51, 0, 0, 0, 35, 0, 0, 0, 0, 0, ] as &[u8] ); } @@ -671,7 +676,8 @@ mod test { .write(b"application/vnd.oasis.opendocument.text") .unwrap(); let result = writer.finish().unwrap(); - assert_eq!(result.get_ref().len(), 159); + + assert_eq!(result.get_ref().len(), 153); let mut v = Vec::new(); v.extend_from_slice(include_bytes!("../tests/data/mimetype.zip")); assert_eq!(result.get_ref(), &v); diff --git a/tests/data/mimetype.zip b/tests/data/mimetype.zip index 78f98224..2d651cbe 100644 Binary files a/tests/data/mimetype.zip and b/tests/data/mimetype.zip differ diff --git a/tests/end_to_end.rs b/tests/end_to_end.rs index cf5986bb..6268920a 100644 --- a/tests/end_to_end.rs +++ b/tests/end_to_end.rs @@ -39,7 +39,7 @@ fn read_zip_file(zip_file: &mut Cursor>) -> zip::result::ZipResult>(); assert_eq!(file_names, expected_file_names);