• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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