From 75f4a84e977a1f409e6580056dc31343e15bbf3e Mon Sep 17 00:00:00 2001 From: Igor Tolmachev Date: Sun, 14 Jul 2024 16:01:10 +0900 Subject: Add support of cp437 encoding --- src/zip/driver.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'src/zip/driver.rs') diff --git a/src/zip/driver.rs b/src/zip/driver.rs index 99b409d..4782e65 100644 --- a/src/zip/driver.rs +++ b/src/zip/driver.rs @@ -1,5 +1,6 @@ use crate::driver::{ArchiveRead, ArchiveWrite, Driver}; use crate::utils::ReadUtils; +use crate::zip::cp437::FromCp437; use crate::zip::structs::{deserialize, Cdr, Eocdr, Eocdr64, Eocdr64Locator, ExtraHeader}; use crate::zip::{ BitFlag, CompressionMethod, ZipError, ZipFileInfo, ZipFileReader, ZipFileWriter, ZipResult, @@ -77,7 +78,7 @@ impl ArchiveRead for Zip { let comment = { let mut buf: Vec = vec![0; eocdr.comment_len as usize]; io.read(&mut buf)?; - String::from_utf8(buf).map_err(|_| ZipError::InvalidArchiveComment)? + String::from_cp437(buf) }; // Try to find eocdr64locator @@ -116,14 +117,23 @@ impl ArchiveRead for Zip { } p += 4; let cdr: Cdr = deserialize(&buf[p..p + 42]).unwrap(); + let bit_flag = BitFlag::new(cdr.bit_flag); p += 42; - let name = String::from_utf8(buf[p..p + cdr.name_len as usize].into()) - .map_err(|_| ZipError::InvalidFileName)?; + let name = if bit_flag.is_utf8() { + String::from_utf8(buf[p..p + cdr.name_len as usize].to_vec()) + .map_err(|_| ZipError::InvalidFileName)? + } else { + String::from_cp437(&buf[p..p + cdr.name_len as usize]) + }; p += cdr.name_len as usize; let extra_fields: Vec = buf[p..p + cdr.extra_field_len as usize].into(); p += cdr.extra_field_len as usize; - let comment = String::from_utf8(buf[p..p + cdr.comment_len as usize].into()) - .map_err(|_| ZipError::InvalidFileComment)?; + let comment = if bit_flag.is_utf8() { + String::from_utf8(buf[p..p + cdr.comment_len as usize].to_vec()) + .map_err(|_| ZipError::InvalidFileComment)? + } else { + String::from_cp437(&buf[p..p + cdr.comment_len as usize]) + }; p += cdr.comment_len as usize; let mut compressed_size = cdr.compressed_size as u64; @@ -209,7 +219,7 @@ impl ArchiveRead for Zip { name.clone(), ZipFileInfo::new( CompressionMethod::from_struct_id(cdr.compression_method)?, - BitFlag::new(cdr.bit_flag), + bit_flag, mtime, atime, ctime, -- cgit v1.2.3