1 // The following is a hexdump of a zip64 file containing the following files:
2 // zero4400: 4400 MB of zeroes
3 // zero100: 100 MB of zeroes
4 // zero4400_2: 4400 MB of zeroes
5 //
6 // 00000000 50 4b 03 04 2d 00 00 00 00 00 1b 6e 51 4d 66 82 |PK..-......nQMf.|
7 // 00000010 13 da ff ff ff ff ff ff ff ff 08 00 30 00 7a 65 |............0.ze|
8 // 00000020 72 6f 34 34 30 30 55 54 09 00 03 a5 21 c7 5b db |ro4400UT....!.[.|
9 // 00000030 21 c7 5b 75 78 0b 00 01 04 e8 03 00 00 04 e8 03 |!.[ux...........|
10 // 00000040 00 00 01 00 10 00 00 00 00 13 01 00 00 00 00 00 |................|
11 // 00000050 00 13 01 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
12 // 00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
13 // *
14 // 113000050 00 00 00 00 00 00 50 4b 03 04 0a 00 00 00 00 00 |......PK........|
15 // 113000060 2b 6e 51 4d 98 23 28 4b 00 00 40 06 00 00 40 06 |+nQM.#(K..@...@.|
16 // 113000070 07 00 1c 00 7a 65 72 6f 31 30 30 55 54 09 00 03 |....zero100UT...|
17 // 113000080 c2 21 c7 5b c2 21 c7 5b 75 78 0b 00 01 04 e8 03 |.!.[.!.[ux......|
18 // 113000090 00 00 04 e8 03 00 00 00 00 00 00 00 00 00 00 00 |................|
19 // 1130000a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
20 // *
21 // 119400090 00 00 00 00 00 00 00 50 4b 03 04 2d 00 00 00 00 |.......PK..-....|
22 // 1194000a0 00 3b 6e 51 4d 66 82 13 da ff ff ff ff ff ff ff |.;nQMf..........|
23 // 1194000b0 ff 0a 00 30 00 7a 65 72 6f 34 34 30 30 5f 32 55 |...0.zero4400_2U|
24 // 1194000c0 54 09 00 03 e2 21 c7 5b db 21 c7 5b 75 78 0b 00 |T....!.[.!.[ux..|
25 // 1194000d0 01 04 e8 03 00 00 04 e8 03 00 00 01 00 10 00 00 |................|
26 // 1194000e0 00 00 13 01 00 00 00 00 00 00 13 01 00 00 00 00 |................|
27 // 1194000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
28 // *
29 // 22c4000e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 50 |...............P|
30 // 22c4000f0 4b 01 02 1e 03 2d 00 00 00 00 00 1b 6e 51 4d 66 |K....-......nQMf|
31 // 22c400100 82 13 da ff ff ff ff ff ff ff ff 08 00 2c 00 00 |.............,..|
32 // 22c400110 00 00 00 00 00 00 00 a4 81 00 00 00 00 7a 65 72 |.............zer|
33 // 22c400120 6f 34 34 30 30 55 54 05 00 03 a5 21 c7 5b 75 78 |o4400UT....!.[ux|
34 // 22c400130 0b 00 01 04 e8 03 00 00 04 e8 03 00 00 01 00 10 |................|
35 // 22c400140 00 00 00 00 13 01 00 00 00 00 00 00 13 01 00 00 |................|
36 // 22c400150 00 50 4b 01 02 1e 03 0a 00 00 00 00 00 2b 6e 51 |.PK..........+nQ|
37 // 22c400160 4d 98 23 28 4b 00 00 40 06 00 00 40 06 07 00 24 |M.#(K..@...@...$|
38 // 22c400170 00 00 00 00 00 00 00 00 00 a4 81 ff ff ff ff 7a |...............z|
39 // 22c400180 65 72 6f 31 30 30 55 54 05 00 03 c2 21 c7 5b 75 |ero100UT....!.[u|
40 // 22c400190 78 0b 00 01 04 e8 03 00 00 04 e8 03 00 00 01 00 |x...............|
41 // 22c4001a0 08 00 56 00 00 13 01 00 00 00 50 4b 01 02 1e 03 |..V.......PK....|
42 // 22c4001b0 2d 00 00 00 00 00 3b 6e 51 4d 66 82 13 da ff ff |-.....;nQMf.....|
43 // 22c4001c0 ff ff ff ff ff ff 0a 00 34 00 00 00 00 00 00 00 |........4.......|
44 // 22c4001d0 00 00 a4 81 ff ff ff ff 7a 65 72 6f 34 34 30 30 |........zero4400|
45 // 22c4001e0 5f 32 55 54 05 00 03 e2 21 c7 5b 75 78 0b 00 01 |_2UT....!.[ux...|
46 // 22c4001f0 04 e8 03 00 00 04 e8 03 00 00 01 00 18 00 00 00 |................|
47 // 22c400200 00 13 01 00 00 00 00 00 00 13 01 00 00 00 97 00 |................|
48 // 22c400210 40 19 01 00 00 00 50 4b 06 06 2c 00 00 00 00 00 |@.....PK..,.....|
49 // 22c400220 00 00 1e 03 2d 00 00 00 00 00 00 00 00 00 03 00 |....-...........|
50 // 22c400230 00 00 00 00 00 00 03 00 00 00 00 00 00 00 27 01 |..............'.|
51 // 22c400240 00 00 00 00 00 00 ef 00 40 2c 02 00 00 00 50 4b |........@,....PK|
52 // 22c400250 06 07 00 00 00 00 16 02 40 2c 02 00 00 00 01 00 |........@,......|
53 // 22c400260 00 00 50 4b 05 06 00 00 00 00 03 00 03 00 27 01 |..PK..........'.|
54 // 22c400270 00 00 ff ff ff ff 00 00 |........|
55 // 22c400278
56 use std::io::{self, Read, Seek, SeekFrom};
57
58 const BLOCK1_LENGTH: u64 = 0x60;
59 const BLOCK1: [u8; BLOCK1_LENGTH as usize] = [
60 0x50, 0x4b, 0x03, 0x04, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x6e, 0x51, 0x4d, 0x66, 0x82,
61 0x13, 0xda, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x30, 0x00, 0x7a, 0x65,
62 0x72, 0x6f, 0x34, 0x34, 0x30, 0x30, 0x55, 0x54, 0x09, 0x00, 0x03, 0xa5, 0x21, 0xc7, 0x5b, 0xdb,
63 0x21, 0xc7, 0x5b, 0x75, 0x78, 0x0b, 0x00, 0x01, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x04, 0xe8, 0x03,
64 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66 ];
67
68 const BLOCK2_LENGTH: u64 = 0x50;
69 const BLOCK2: [u8; BLOCK2_LENGTH as usize] = [
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4b, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
71 0x2b, 0x6e, 0x51, 0x4d, 0x98, 0x23, 0x28, 0x4b, 0x00, 0x00, 0x40, 0x06, 0x00, 0x00, 0x40, 0x06,
72 0x07, 0x00, 0x1c, 0x00, 0x7a, 0x65, 0x72, 0x6f, 0x31, 0x30, 0x30, 0x55, 0x54, 0x09, 0x00, 0x03,
73 0xc2, 0x21, 0xc7, 0x5b, 0xc2, 0x21, 0xc7, 0x5b, 0x75, 0x78, 0x0b, 0x00, 0x01, 0x04, 0xe8, 0x03,
74 0x00, 0x00, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
75 ];
76
77 const BLOCK3_LENGTH: u64 = 0x60;
78 const BLOCK3: [u8; BLOCK3_LENGTH as usize] = [
79 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4b, 0x03, 0x04, 0x2d, 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x3b, 0x6e, 0x51, 0x4d, 0x66, 0x82, 0x13, 0xda, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
81 0xff, 0x0a, 0x00, 0x30, 0x00, 0x7a, 0x65, 0x72, 0x6f, 0x34, 0x34, 0x30, 0x30, 0x5f, 0x32, 0x55,
82 0x54, 0x09, 0x00, 0x03, 0xe2, 0x21, 0xc7, 0x5b, 0xdb, 0x21, 0xc7, 0x5b, 0x75, 0x78, 0x0b, 0x00,
83 0x01, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00,
84 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00,
85 ];
86
87 const BLOCK4_LENGTH: u64 = 0x198;
88 const BLOCK4: [u8; BLOCK4_LENGTH as usize] = [
89 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
90 0x4b, 0x01, 0x02, 0x1e, 0x03, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x6e, 0x51, 0x4d, 0x66,
91 0x82, 0x13, 0xda, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x2c, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x81, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x65, 0x72,
93 0x6f, 0x34, 0x34, 0x30, 0x30, 0x55, 0x54, 0x05, 0x00, 0x03, 0xa5, 0x21, 0xc7, 0x5b, 0x75, 0x78,
94 0x0b, 0x00, 0x01, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x01, 0x00, 0x10,
95 0x00, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00,
96 0x00, 0x50, 0x4b, 0x01, 0x02, 0x1e, 0x03, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x6e, 0x51,
97 0x4d, 0x98, 0x23, 0x28, 0x4b, 0x00, 0x00, 0x40, 0x06, 0x00, 0x00, 0x40, 0x06, 0x07, 0x00, 0x24,
98 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x81, 0xff, 0xff, 0xff, 0xff, 0x7a,
99 0x65, 0x72, 0x6f, 0x31, 0x30, 0x30, 0x55, 0x54, 0x05, 0x00, 0x03, 0xc2, 0x21, 0xc7, 0x5b, 0x75,
100 0x78, 0x0b, 0x00, 0x01, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x01, 0x00,
101 0x08, 0x00, 0x56, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x50, 0x4b, 0x01, 0x02, 0x1e, 0x03,
102 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x6e, 0x51, 0x4d, 0x66, 0x82, 0x13, 0xda, 0xff, 0xff,
103 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0a, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104 0x00, 0x00, 0xa4, 0x81, 0xff, 0xff, 0xff, 0xff, 0x7a, 0x65, 0x72, 0x6f, 0x34, 0x34, 0x30, 0x30,
105 0x5f, 0x32, 0x55, 0x54, 0x05, 0x00, 0x03, 0xe2, 0x21, 0xc7, 0x5b, 0x75, 0x78, 0x0b, 0x00, 0x01,
106 0x04, 0xe8, 0x03, 0x00, 0x00, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00,
107 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x97, 0x00,
108 0x40, 0x19, 0x01, 0x00, 0x00, 0x00, 0x50, 0x4b, 0x06, 0x06, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00,
109 0x00, 0x00, 0x1e, 0x03, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x01,
111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0x00, 0x40, 0x2c, 0x02, 0x00, 0x00, 0x00, 0x50, 0x4b,
112 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x16, 0x02, 0x40, 0x2c, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00,
113 0x00, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x27, 0x01,
114 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
115 ];
116
117 const BLOCK1_START: u64 = 0x000000000;
118 const BLOCK2_START: u64 = 0x113000050;
119 const BLOCK3_START: u64 = 0x119400090;
120 const BLOCK4_START: u64 = 0x22c4000e0;
121
122 const BLOCK1_END: u64 = BLOCK1_START + BLOCK1_LENGTH - 1;
123 const BLOCK2_END: u64 = BLOCK2_START + BLOCK2_LENGTH - 1;
124 const BLOCK3_END: u64 = BLOCK3_START + BLOCK3_LENGTH - 1;
125 const BLOCK4_END: u64 = BLOCK4_START + BLOCK4_LENGTH - 1;
126
127 const TOTAL_LENGTH: u64 = BLOCK4_START + BLOCK4_LENGTH;
128
129 struct Zip64File {
130 pointer: u64,
131 }
132
133 impl Zip64File {
new() -> Self134 fn new() -> Self {
135 Zip64File { pointer: 0 }
136 }
137 }
138
139 impl Seek for Zip64File {
seek(&mut self, pos: SeekFrom) -> io::Result<u64>140 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
141 match pos {
142 SeekFrom::Start(offset) => {
143 self.pointer = offset;
144 }
145 SeekFrom::End(offset) => {
146 if offset > 0 || offset < -(TOTAL_LENGTH as i64) {
147 return Err(io::Error::new(io::ErrorKind::Other, "Invalid seek offset"));
148 }
149 self.pointer = (TOTAL_LENGTH as i64 + offset) as u64;
150 }
151 SeekFrom::Current(offset) => {
152 let seekpos = self.pointer as i64 + offset;
153 if seekpos < 0 || seekpos as u64 > TOTAL_LENGTH {
154 return Err(io::Error::new(io::ErrorKind::Other, "Invalid seek offset"));
155 }
156 self.pointer = seekpos as u64;
157 }
158 }
159 Ok(self.pointer)
160 }
161 }
162
163 impl Read for Zip64File {
read(&mut self, buf: &mut [u8]) -> io::Result<usize>164 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
165 if self.pointer >= TOTAL_LENGTH {
166 return Ok(0);
167 }
168 match self.pointer {
169 BLOCK1_START..=BLOCK1_END => {
170 buf[0] = BLOCK1[(self.pointer - BLOCK1_START) as usize];
171 }
172 BLOCK2_START..=BLOCK2_END => {
173 buf[0] = BLOCK2[(self.pointer - BLOCK2_START) as usize];
174 }
175 BLOCK3_START..=BLOCK3_END => {
176 buf[0] = BLOCK3[(self.pointer - BLOCK3_START) as usize];
177 }
178 BLOCK4_START..=BLOCK4_END => {
179 buf[0] = BLOCK4[(self.pointer - BLOCK4_START) as usize];
180 }
181 _ => {
182 buf[0] = 0;
183 }
184 }
185 self.pointer += 1;
186 Ok(1)
187 }
188 }
189
190 #[test]
zip64_large()191 fn zip64_large() {
192 let zipfile = Zip64File::new();
193 let mut archive = zip::ZipArchive::new(zipfile).unwrap();
194 let mut buf = [0u8; 32];
195
196 for i in 0..archive.len() {
197 let mut file = archive.by_index(i).unwrap();
198 let outpath = file.enclosed_name().unwrap();
199 println!(
200 "Entry {} has name \"{}\" ({} bytes)",
201 i,
202 outpath.display(),
203 file.size()
204 );
205
206 match file.read_exact(&mut buf) {
207 Ok(()) => println!("The first {} bytes are: {:?}", buf.len(), buf),
208 Err(e) => println!("Could not read the file: {:?}", e),
209 };
210 }
211 }
212