transfert file from zip to another (wip)
This commit is contained in:
parent
0d305fbe62
commit
0fdf619360
10 changed files with 512 additions and 273 deletions
73
apk_frauder/src/zip_writer.rs
Normal file
73
apk_frauder/src/zip_writer.rs
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
use std::io::{Read, Seek, SeekFrom, Write};
|
||||
|
||||
use crate::{
|
||||
end_of_central_directory::EndCentralDirectory,
|
||||
end_of_central_directory::Zip64EndCentralDirectory, FileInfo, ZipFileReader,
|
||||
};
|
||||
use androscalpel_serializer::Serializable;
|
||||
|
||||
pub struct ZipFileWriter<T: Write> {
|
||||
files: Vec<FileInfo>,
|
||||
zip64_end_of_central_directory: Option<Zip64EndCentralDirectory>,
|
||||
current_offset: u64,
|
||||
data: T,
|
||||
}
|
||||
|
||||
impl<T: Write> ZipFileWriter<T> {
|
||||
pub fn new(writer: T, zip64_info: Option<Zip64EndCentralDirectory>) -> Self {
|
||||
Self {
|
||||
current_offset: 0,
|
||||
zip64_end_of_central_directory: zip64_info,
|
||||
files: vec![],
|
||||
data: writer,
|
||||
}
|
||||
}
|
||||
|
||||
/// Insert an file from an existing zip
|
||||
pub fn insert_file_from_zip<U: Read + Seek>(
|
||||
&mut self,
|
||||
mut file_info: FileInfo,
|
||||
zip_file: &mut ZipFileReader<U>,
|
||||
) {
|
||||
let file_off = file_info.get_file_offset();
|
||||
let file_size = file_info.get_compressed_size();
|
||||
file_info.set_offset_local_header(self.current_offset);
|
||||
file_info.local_header.serialize(&mut self.data).unwrap();
|
||||
zip_file.data.seek(SeekFrom::Start(file_off)).unwrap();
|
||||
let mut remaining_size = file_size;
|
||||
let mut buffer = [0u8; 4096];
|
||||
while remaining_size != 0 {
|
||||
let read = zip_file
|
||||
.data
|
||||
.read(&mut buffer[0..core::cmp::min(4096, remaining_size as usize)])
|
||||
.unwrap();
|
||||
self.data.write_all(&buffer[0..read]).unwrap();
|
||||
remaining_size -= read as u64;
|
||||
}
|
||||
self.current_offset += file_info.local_header.size() as u64 + file_size;
|
||||
self.files.push(file_info);
|
||||
}
|
||||
|
||||
/// Finish the zip file by writing the central directory.
|
||||
pub fn write_central_directory(&mut self) {
|
||||
for file_info in &self.files {
|
||||
file_info.header.serialize(&mut self.data).unwrap();
|
||||
}
|
||||
// TODO: zip64
|
||||
EndCentralDirectory {
|
||||
disk_number: 0,
|
||||
disk_number_of_central_directory_start: 0,
|
||||
number_of_entries_in_central_directory_on_disk: self.files.len() as u16,
|
||||
number_of_entries_in_central_directory: self.files.len() as u16,
|
||||
size_central_directory: self
|
||||
.files
|
||||
.iter()
|
||||
.map(|file| file.local_header.size() as u32 + file.get_compressed_size() as u32)
|
||||
.sum(),
|
||||
offset_central_directory: self.current_offset as u32,
|
||||
comment: vec![],
|
||||
}
|
||||
.serialize(&mut self.data)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue