use std::fs::File;
use std::io::{Seek, Write};
use tempfile::tempdir;
#[test]
fn read_zip64_crafted() {
use s_zip::StreamingZipReader;
let dir = tempdir().unwrap();
let path = dir.path().join("zip64_test.zip");
let mut f = File::create(&path).unwrap();
f.write_all(&[0x50, 0x4b, 0x03, 0x04]).unwrap();
f.write_all(&[20, 0]).unwrap();
f.write_all(&[8, 0]).unwrap();
f.write_all(&[0, 0]).unwrap();
f.write_all(&[0, 0, 0, 0]).unwrap();
f.write_all(&0u32.to_le_bytes()).unwrap();
f.write_all(&0xFFFFFFFFu32.to_le_bytes()).unwrap();
f.write_all(&0xFFFFFFFFu32.to_le_bytes()).unwrap();
f.write_all(&(5u16).to_le_bytes()).unwrap();
f.write_all(&0u16.to_le_bytes()).unwrap();
f.write_all(b"a.txt").unwrap();
let data = b"hello";
let data_offset = f.stream_position().unwrap();
f.write_all(data).unwrap();
let crc = crc32fast::hash(data);
f.write_all(&[0x50, 0x4b, 0x07, 0x08]).unwrap();
f.write_all(&crc.to_le_bytes()).unwrap();
f.write_all(&(data.len() as u64).to_le_bytes()).unwrap();
f.write_all(&(data.len() as u64).to_le_bytes()).unwrap();
let cd_start = f.stream_position().unwrap();
f.write_all(&[0x50, 0x4b, 0x01, 0x02]).unwrap();
f.write_all(&[20, 0]).unwrap(); f.write_all(&[20, 0]).unwrap(); f.write_all(&[8, 0]).unwrap(); f.write_all(&[0, 0]).unwrap(); f.write_all(&[0, 0, 0, 0]).unwrap(); f.write_all(&crc.to_le_bytes()).unwrap();
f.write_all(&0xFFFFFFFFu32.to_le_bytes()).unwrap();
f.write_all(&0xFFFFFFFFu32.to_le_bytes()).unwrap();
f.write_all(&(5u16).to_le_bytes()).unwrap(); f.write_all(&(28u16).to_le_bytes()).unwrap();
f.write_all(&0u16.to_le_bytes()).unwrap(); f.write_all(&0u16.to_le_bytes()).unwrap(); f.write_all(&0u16.to_le_bytes()).unwrap(); f.write_all(&0u32.to_le_bytes()).unwrap(); f.write_all(&0xFFFFFFFFu32.to_le_bytes()).unwrap();
f.write_all(b"a.txt").unwrap();
f.write_all(&0x0001u16.to_le_bytes()).unwrap();
f.write_all(&(24u16).to_le_bytes()).unwrap();
f.write_all(&(data.len() as u64).to_le_bytes()).unwrap();
f.write_all(&(data.len() as u64).to_le_bytes()).unwrap();
f.write_all(&(data_offset - 30).to_le_bytes()).unwrap();
let cd_end = f.stream_position().unwrap();
let cd_size = cd_end - cd_start;
let zip64_eocd_start = f.stream_position().unwrap();
f.write_all(&[0x50, 0x4b, 0x06, 0x06]).unwrap(); f.write_all(&(44u64).to_le_bytes()).unwrap();
f.write_all(&[20, 0]).unwrap(); f.write_all(&[20, 0]).unwrap(); f.write_all(&0u32.to_le_bytes()).unwrap(); f.write_all(&0u32.to_le_bytes()).unwrap(); f.write_all(&(1u64).to_le_bytes()).unwrap(); f.write_all(&(1u64).to_le_bytes()).unwrap(); f.write_all(&cd_size.to_le_bytes()).unwrap(); f.write_all(&cd_start.to_le_bytes()).unwrap();
f.write_all(&[0x50, 0x4b, 0x06, 0x07]).unwrap();
f.write_all(&0u32.to_le_bytes()).unwrap(); f.write_all(&zip64_eocd_start.to_le_bytes()).unwrap(); f.write_all(&0u32.to_le_bytes()).unwrap();
f.write_all(&[0x50, 0x4b, 0x05, 0x06]).unwrap();
f.write_all(&0u16.to_le_bytes()).unwrap(); f.write_all(&0u16.to_le_bytes()).unwrap(); f.write_all(&0xFFFFu16.to_le_bytes()).unwrap(); f.write_all(&0xFFFFu16.to_le_bytes()).unwrap(); f.write_all(&0xFFFFFFFFu32.to_le_bytes()).unwrap(); f.write_all(&0xFFFFFFFFu32.to_le_bytes()).unwrap(); f.write_all(&0u16.to_le_bytes()).unwrap();
f.flush().unwrap();
let reader = StreamingZipReader::open(&path).expect("should open crafted zip64");
let entries = reader.entries();
assert_eq!(entries.len(), 1);
let e = &entries[0];
assert_eq!(e.name, "a.txt");
assert_eq!(e.uncompressed_size, data.len() as u64);
}