aboutsummaryrefslogtreecommitdiff
path: root/src/zip/driver.rs
diff options
context:
space:
mode:
authorigorechek06 <me@igorek.dev>2024-08-10 17:18:03 +0900
committerigorechek06 <me@igorek.dev>2024-08-10 17:18:43 +0900
commit866516ac50851e2827e6aff0a98c444268c566ff (patch)
tree1134bf6f714d75a1050befa0f67bddd2d4b085c8 /src/zip/driver.rs
parent51f2737ca7af016e3dd3ad03673f48a754a1642e (diff)
downloadarchivator-866516ac50851e2827e6aff0a98c444268c566ff.tar.gz
archivator-866516ac50851e2827e6aff0a98c444268c566ff.zip
Add overlap checking
Diffstat (limited to 'src/zip/driver.rs')
-rw-r--r--src/zip/driver.rs26
1 files changed, 18 insertions, 8 deletions
diff --git a/src/zip/driver.rs b/src/zip/driver.rs
index b4217c8..9dccfd0 100644
--- a/src/zip/driver.rs
+++ b/src/zip/driver.rs
@@ -1,5 +1,5 @@
1use crate::driver::{ArchiveRead, ArchiveWrite, Driver}; 1use crate::driver::{ArchiveRead, ArchiveWrite, Driver};
2use crate::utils::ReadUtils; 2use crate::utils::{IoCursor, ReadUtils};
3use crate::zip::cp437::FromCp437; 3use crate::zip::cp437::FromCp437;
4use crate::zip::datetime::DosDateTime; 4use crate::zip::datetime::DosDateTime;
5use crate::zip::structs::{ 5use crate::zip::structs::{
@@ -106,12 +106,19 @@ impl<Io: Read + Seek> ArchiveRead for Zip<Io> {
106 io.seek(SeekFrom::Start(eocdr64locator.eocdr64_pointer))?; 106 io.seek(SeekFrom::Start(eocdr64locator.eocdr64_pointer))?;
107 let buf = io.read_arr::<56>()?; 107 let buf = io.read_arr::<56>()?;
108 if buf[0..4] != EOCDR64_SIGNATURE { 108 if buf[0..4] != EOCDR64_SIGNATURE {
109 return Err(ZipError::InvalidEOCDR64Signature); 109 return Err(ZipError::InvalidEocdr64Signature);
110 } 110 }
111 let eocdr64: Eocdr64 = deserialize(&buf[4..]).unwrap(); 111 let eocdr64: Eocdr64 = deserialize(&buf[4..]).unwrap();
112 if eocdr64.cd_pointer + eocdr64.cd_size > eocdr64locator.eocdr64_pointer {
113 return Err(ZipError::Overlapping("Central directory records", "Zip64 end of central directory record"));
114 }
112 115
113 (eocdr64.cd_pointer, eocdr64.cd_size, eocdr64.cd_records) 116 (eocdr64.cd_pointer, eocdr64.cd_size, eocdr64.cd_records)
114 } else { 117 } else {
118 if (eocdr.cd_pointer + eocdr.cd_size) as u64 > pos {
119 return Err(ZipError::Overlapping("Central directory records", "End of central directory record"));
120 }
121
115 ( 122 (
116 eocdr.cd_pointer as u64, 123 eocdr.cd_pointer as u64,
117 eocdr.cd_size as u64, 124 eocdr.cd_size as u64,
@@ -123,27 +130,30 @@ impl<Io: Read + Seek> ArchiveRead for Zip<Io> {
123 let mut indexes = Map::with_capacity(cd_records as usize); 130 let mut indexes = Map::with_capacity(cd_records as usize);
124 let mut files = Vec::with_capacity(cd_records as usize); 131 let mut files = Vec::with_capacity(cd_records as usize);
125 io.seek(SeekFrom::Start(cd_pointer))?; 132 io.seek(SeekFrom::Start(cd_pointer))?;
126 let mut buf_reader = BufReader::with_capacity(cd_size.min(131072) as usize, &mut io); 133 let mut cd_reader = BufReader::with_capacity(
134 cd_size.min(131072) as usize,
135 IoCursor::new(&mut io, cd_pointer, cd_pointer + cd_size),
136 );
127 137
128 for i in 0..cd_records as usize { 138 for i in 0..cd_records as usize {
129 let buf = buf_reader.read_arr::<46>()?; 139 let buf = cd_reader.read_arr::<46>()?;
130 140
131 if buf[..4] != CDR_SIGNATURE { 141 if buf[..4] != CDR_SIGNATURE {
132 return Err(ZipError::InvalidCDRSignature); 142 return Err(ZipError::InvalidCdrSignature);
133 } 143 }
134 let cdr: Cdr = deserialize(&buf[4..46]).unwrap(); 144 let cdr: Cdr = deserialize(&buf[4..46]).unwrap();
135 let bit_flag = BitFlag::new(cdr.bit_flag); 145 let bit_flag = BitFlag::new(cdr.bit_flag);
136 146
137 let name = buf_reader.read_vec(cdr.name_len as usize)?; 147 let name = cd_reader.read_vec(cdr.name_len as usize)?;
138 let name = if bit_flag.is_utf8() { 148 let name = if bit_flag.is_utf8() {
139 String::from_utf8(name).map_err(|_| ZipError::InvalidFileName)? 149 String::from_utf8(name).map_err(|_| ZipError::InvalidFileName)?
140 } else { 150 } else {
141 String::from_cp437(name) 151 String::from_cp437(name)
142 }; 152 };
143 153
144 let extra_fields = buf_reader.read_vec(cdr.extra_field_len as usize)?; 154 let extra_fields = cd_reader.read_vec(cdr.extra_field_len as usize)?;
145 155
146 let comment = buf_reader.read_vec(cdr.comment_len as usize)?; 156 let comment = cd_reader.read_vec(cdr.comment_len as usize)?;
147 let comment = if bit_flag.is_utf8() { 157 let comment = if bit_flag.is_utf8() {
148 String::from_utf8(comment).map_err(|_| ZipError::InvalidFileComment)? 158 String::from_utf8(comment).map_err(|_| ZipError::InvalidFileComment)?
149 } else { 159 } else {