Coverage Report

Created: 2025-11-11 06:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/zip/src/spec.rs
Line
Count
Source
1
use crate::result::{ZipError, ZipResult};
2
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
3
use std::io;
4
use std::io::prelude::*;
5
6
pub const LOCAL_FILE_HEADER_SIGNATURE: u32 = 0x04034b50;
7
pub const CENTRAL_DIRECTORY_HEADER_SIGNATURE: u32 = 0x02014b50;
8
const CENTRAL_DIRECTORY_END_SIGNATURE: u32 = 0x06054b50;
9
pub const ZIP64_CENTRAL_DIRECTORY_END_SIGNATURE: u32 = 0x06064b50;
10
const ZIP64_CENTRAL_DIRECTORY_END_LOCATOR_SIGNATURE: u32 = 0x07064b50;
11
12
pub const ZIP64_BYTES_THR: u64 = u32::MAX as u64;
13
pub const ZIP64_ENTRY_THR: usize = u16::MAX as usize;
14
15
pub struct CentralDirectoryEnd {
16
    pub disk_number: u16,
17
    pub disk_with_central_directory: u16,
18
    pub number_of_files_on_this_disk: u16,
19
    pub number_of_files: u16,
20
    pub central_directory_size: u32,
21
    pub central_directory_offset: u32,
22
    pub zip_file_comment: Vec<u8>,
23
}
24
25
impl CentralDirectoryEnd {
26
    // Per spec 4.4.1.4 - a CentralDirectoryEnd field might be insufficient to hold the
27
    // required data. In this case the file SHOULD contain a ZIP64 format record
28
    // and the field of this record will be set to -1
29
4.21k
    pub(crate) fn record_too_small(&self) -> bool {
30
4.21k
        self.disk_number == 0xFFFF
31
3.64k
            || self.disk_with_central_directory == 0xFFFF
32
3.24k
            || self.number_of_files_on_this_disk == 0xFFFF
33
3.09k
            || self.number_of_files == 0xFFFF
34
2.74k
            || self.central_directory_size == 0xFFFFFFFF
35
2.72k
            || self.central_directory_offset == 0xFFFFFFFF
36
4.21k
    }
37
38
3.54k
    pub fn parse<T: Read>(reader: &mut T) -> ZipResult<CentralDirectoryEnd> {
39
3.54k
        let magic = reader.read_u32::<LittleEndian>()?;
40
3.54k
        if magic != CENTRAL_DIRECTORY_END_SIGNATURE {
41
0
            return Err(ZipError::InvalidArchive("Invalid digital signature header"));
42
3.54k
        }
43
3.54k
        let disk_number = reader.read_u16::<LittleEndian>()?;
44
3.54k
        let disk_with_central_directory = reader.read_u16::<LittleEndian>()?;
45
3.54k
        let number_of_files_on_this_disk = reader.read_u16::<LittleEndian>()?;
46
3.54k
        let number_of_files = reader.read_u16::<LittleEndian>()?;
47
3.54k
        let central_directory_size = reader.read_u32::<LittleEndian>()?;
48
3.54k
        let central_directory_offset = reader.read_u32::<LittleEndian>()?;
49
3.54k
        let zip_file_comment_length = reader.read_u16::<LittleEndian>()? as usize;
50
3.54k
        let mut zip_file_comment = vec![0; zip_file_comment_length];
51
3.54k
        reader.read_exact(&mut zip_file_comment)?;
52
53
3.51k
        Ok(CentralDirectoryEnd {
54
3.51k
            disk_number,
55
3.51k
            disk_with_central_directory,
56
3.51k
            number_of_files_on_this_disk,
57
3.51k
            number_of_files,
58
3.51k
            central_directory_size,
59
3.51k
            central_directory_offset,
60
3.51k
            zip_file_comment,
61
3.51k
        })
62
3.54k
    }
<zip::spec::CentralDirectoryEnd>::parse::<std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
38
2.37k
    pub fn parse<T: Read>(reader: &mut T) -> ZipResult<CentralDirectoryEnd> {
39
2.37k
        let magic = reader.read_u32::<LittleEndian>()?;
40
2.37k
        if magic != CENTRAL_DIRECTORY_END_SIGNATURE {
41
0
            return Err(ZipError::InvalidArchive("Invalid digital signature header"));
42
2.37k
        }
43
2.37k
        let disk_number = reader.read_u16::<LittleEndian>()?;
44
2.37k
        let disk_with_central_directory = reader.read_u16::<LittleEndian>()?;
45
2.37k
        let number_of_files_on_this_disk = reader.read_u16::<LittleEndian>()?;
46
2.37k
        let number_of_files = reader.read_u16::<LittleEndian>()?;
47
2.37k
        let central_directory_size = reader.read_u32::<LittleEndian>()?;
48
2.37k
        let central_directory_offset = reader.read_u32::<LittleEndian>()?;
49
2.37k
        let zip_file_comment_length = reader.read_u16::<LittleEndian>()? as usize;
50
2.37k
        let mut zip_file_comment = vec![0; zip_file_comment_length];
51
2.37k
        reader.read_exact(&mut zip_file_comment)?;
52
53
2.34k
        Ok(CentralDirectoryEnd {
54
2.34k
            disk_number,
55
2.34k
            disk_with_central_directory,
56
2.34k
            number_of_files_on_this_disk,
57
2.34k
            number_of_files,
58
2.34k
            central_directory_size,
59
2.34k
            central_directory_offset,
60
2.34k
            zip_file_comment,
61
2.34k
        })
62
2.37k
    }
<zip::spec::CentralDirectoryEnd>::parse::<std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
38
423
    pub fn parse<T: Read>(reader: &mut T) -> ZipResult<CentralDirectoryEnd> {
39
423
        let magic = reader.read_u32::<LittleEndian>()?;
40
423
        if magic != CENTRAL_DIRECTORY_END_SIGNATURE {
41
0
            return Err(ZipError::InvalidArchive("Invalid digital signature header"));
42
423
        }
43
423
        let disk_number = reader.read_u16::<LittleEndian>()?;
44
423
        let disk_with_central_directory = reader.read_u16::<LittleEndian>()?;
45
423
        let number_of_files_on_this_disk = reader.read_u16::<LittleEndian>()?;
46
423
        let number_of_files = reader.read_u16::<LittleEndian>()?;
47
423
        let central_directory_size = reader.read_u32::<LittleEndian>()?;
48
423
        let central_directory_offset = reader.read_u32::<LittleEndian>()?;
49
423
        let zip_file_comment_length = reader.read_u16::<LittleEndian>()? as usize;
50
423
        let mut zip_file_comment = vec![0; zip_file_comment_length];
51
423
        reader.read_exact(&mut zip_file_comment)?;
52
53
420
        Ok(CentralDirectoryEnd {
54
420
            disk_number,
55
420
            disk_with_central_directory,
56
420
            number_of_files_on_this_disk,
57
420
            number_of_files,
58
420
            central_directory_size,
59
420
            central_directory_offset,
60
420
            zip_file_comment,
61
420
        })
62
423
    }
<zip::spec::CentralDirectoryEnd>::parse::<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>
Line
Count
Source
38
748
    pub fn parse<T: Read>(reader: &mut T) -> ZipResult<CentralDirectoryEnd> {
39
748
        let magic = reader.read_u32::<LittleEndian>()?;
40
748
        if magic != CENTRAL_DIRECTORY_END_SIGNATURE {
41
0
            return Err(ZipError::InvalidArchive("Invalid digital signature header"));
42
748
        }
43
748
        let disk_number = reader.read_u16::<LittleEndian>()?;
44
748
        let disk_with_central_directory = reader.read_u16::<LittleEndian>()?;
45
748
        let number_of_files_on_this_disk = reader.read_u16::<LittleEndian>()?;
46
748
        let number_of_files = reader.read_u16::<LittleEndian>()?;
47
748
        let central_directory_size = reader.read_u32::<LittleEndian>()?;
48
748
        let central_directory_offset = reader.read_u32::<LittleEndian>()?;
49
748
        let zip_file_comment_length = reader.read_u16::<LittleEndian>()? as usize;
50
748
        let mut zip_file_comment = vec![0; zip_file_comment_length];
51
748
        reader.read_exact(&mut zip_file_comment)?;
52
53
748
        Ok(CentralDirectoryEnd {
54
748
            disk_number,
55
748
            disk_with_central_directory,
56
748
            number_of_files_on_this_disk,
57
748
            number_of_files,
58
748
            central_directory_size,
59
748
            central_directory_offset,
60
748
            zip_file_comment,
61
748
        })
62
748
    }
63
64
14.6k
    pub fn find_and_parse<T: Read + io::Seek>(
65
14.6k
        reader: &mut T,
66
14.6k
    ) -> ZipResult<(CentralDirectoryEnd, u64)> {
67
        const HEADER_SIZE: u64 = 22;
68
        const BYTES_BETWEEN_MAGIC_AND_COMMENT_SIZE: u64 = HEADER_SIZE - 6;
69
14.6k
        let file_length = reader.seek(io::SeekFrom::End(0))?;
70
71
14.6k
        let search_upper_bound = file_length.saturating_sub(HEADER_SIZE + ::std::u16::MAX as u64);
72
73
14.6k
        if file_length < HEADER_SIZE {
74
93
            return Err(ZipError::InvalidArchive("Invalid zip header"));
75
14.5k
        }
76
77
14.5k
        let mut pos = file_length - HEADER_SIZE;
78
759M
        while pos >= search_upper_bound {
79
759M
            reader.seek(io::SeekFrom::Start(pos))?;
80
759M
            if reader.read_u32::<LittleEndian>()? == CENTRAL_DIRECTORY_END_SIGNATURE {
81
3.54k
                reader.seek(io::SeekFrom::Current(
82
3.54k
                    BYTES_BETWEEN_MAGIC_AND_COMMENT_SIZE as i64,
83
3.54k
                ))?;
84
3.54k
                let cde_start_pos = reader.seek(io::SeekFrom::Start(pos))?;
85
3.54k
                return CentralDirectoryEnd::parse(reader).map(|cde| (cde, cde_start_pos));
<zip::spec::CentralDirectoryEnd>::find_and_parse::<std::io::cursor::Cursor<&[u8]>>::{closure#0}
Line
Count
Source
85
2.34k
                return CentralDirectoryEnd::parse(reader).map(|cde| (cde, cde_start_pos));
<zip::spec::CentralDirectoryEnd>::find_and_parse::<std::io::cursor::Cursor<&[u8]>>::{closure#0}
Line
Count
Source
85
420
                return CentralDirectoryEnd::parse(reader).map(|cde| (cde, cde_start_pos));
<zip::spec::CentralDirectoryEnd>::find_and_parse::<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>::{closure#0}
Line
Count
Source
85
748
                return CentralDirectoryEnd::parse(reader).map(|cde| (cde, cde_start_pos));
86
759M
            }
87
759M
            pos = match pos.checked_sub(1) {
88
759M
                Some(p) => p,
89
63
                None => break,
90
            };
91
        }
92
11.0k
        Err(ZipError::InvalidArchive(
93
11.0k
            "Could not find central directory end",
94
11.0k
        ))
95
14.6k
    }
<zip::spec::CentralDirectoryEnd>::find_and_parse::<std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
64
2.46k
    pub fn find_and_parse<T: Read + io::Seek>(
65
2.46k
        reader: &mut T,
66
2.46k
    ) -> ZipResult<(CentralDirectoryEnd, u64)> {
67
        const HEADER_SIZE: u64 = 22;
68
        const BYTES_BETWEEN_MAGIC_AND_COMMENT_SIZE: u64 = HEADER_SIZE - 6;
69
2.46k
        let file_length = reader.seek(io::SeekFrom::End(0))?;
70
71
2.46k
        let search_upper_bound = file_length.saturating_sub(HEADER_SIZE + ::std::u16::MAX as u64);
72
73
2.46k
        if file_length < HEADER_SIZE {
74
32
            return Err(ZipError::InvalidArchive("Invalid zip header"));
75
2.43k
        }
76
77
2.43k
        let mut pos = file_length - HEADER_SIZE;
78
2.35M
        while pos >= search_upper_bound {
79
2.35M
            reader.seek(io::SeekFrom::Start(pos))?;
80
2.35M
            if reader.read_u32::<LittleEndian>()? == CENTRAL_DIRECTORY_END_SIGNATURE {
81
2.37k
                reader.seek(io::SeekFrom::Current(
82
2.37k
                    BYTES_BETWEEN_MAGIC_AND_COMMENT_SIZE as i64,
83
2.37k
                ))?;
84
2.37k
                let cde_start_pos = reader.seek(io::SeekFrom::Start(pos))?;
85
2.37k
                return CentralDirectoryEnd::parse(reader).map(|cde| (cde, cde_start_pos));
86
2.35M
            }
87
2.35M
            pos = match pos.checked_sub(1) {
88
2.35M
                Some(p) => p,
89
55
                None => break,
90
            };
91
        }
92
64
        Err(ZipError::InvalidArchive(
93
64
            "Could not find central directory end",
94
64
        ))
95
2.46k
    }
<zip::spec::CentralDirectoryEnd>::find_and_parse::<std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
64
506
    pub fn find_and_parse<T: Read + io::Seek>(
65
506
        reader: &mut T,
66
506
    ) -> ZipResult<(CentralDirectoryEnd, u64)> {
67
        const HEADER_SIZE: u64 = 22;
68
        const BYTES_BETWEEN_MAGIC_AND_COMMENT_SIZE: u64 = HEADER_SIZE - 6;
69
506
        let file_length = reader.seek(io::SeekFrom::End(0))?;
70
71
506
        let search_upper_bound = file_length.saturating_sub(HEADER_SIZE + ::std::u16::MAX as u64);
72
73
506
        if file_length < HEADER_SIZE {
74
61
            return Err(ZipError::InvalidArchive("Invalid zip header"));
75
445
        }
76
77
445
        let mut pos = file_length - HEADER_SIZE;
78
7.93M
        while pos >= search_upper_bound {
79
7.93M
            reader.seek(io::SeekFrom::Start(pos))?;
80
7.93M
            if reader.read_u32::<LittleEndian>()? == CENTRAL_DIRECTORY_END_SIGNATURE {
81
423
                reader.seek(io::SeekFrom::Current(
82
423
                    BYTES_BETWEEN_MAGIC_AND_COMMENT_SIZE as i64,
83
423
                ))?;
84
423
                let cde_start_pos = reader.seek(io::SeekFrom::Start(pos))?;
85
423
                return CentralDirectoryEnd::parse(reader).map(|cde| (cde, cde_start_pos));
86
7.93M
            }
87
7.93M
            pos = match pos.checked_sub(1) {
88
7.93M
                Some(p) => p,
89
8
                None => break,
90
            };
91
        }
92
22
        Err(ZipError::InvalidArchive(
93
22
            "Could not find central directory end",
94
22
        ))
95
506
    }
<zip::spec::CentralDirectoryEnd>::find_and_parse::<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>
Line
Count
Source
64
11.6k
    pub fn find_and_parse<T: Read + io::Seek>(
65
11.6k
        reader: &mut T,
66
11.6k
    ) -> ZipResult<(CentralDirectoryEnd, u64)> {
67
        const HEADER_SIZE: u64 = 22;
68
        const BYTES_BETWEEN_MAGIC_AND_COMMENT_SIZE: u64 = HEADER_SIZE - 6;
69
11.6k
        let file_length = reader.seek(io::SeekFrom::End(0))?;
70
71
11.6k
        let search_upper_bound = file_length.saturating_sub(HEADER_SIZE + ::std::u16::MAX as u64);
72
73
11.6k
        if file_length < HEADER_SIZE {
74
0
            return Err(ZipError::InvalidArchive("Invalid zip header"));
75
11.6k
        }
76
77
11.6k
        let mut pos = file_length - HEADER_SIZE;
78
749M
        while pos >= search_upper_bound {
79
749M
            reader.seek(io::SeekFrom::Start(pos))?;
80
749M
            if reader.read_u32::<LittleEndian>()? == CENTRAL_DIRECTORY_END_SIGNATURE {
81
748
                reader.seek(io::SeekFrom::Current(
82
748
                    BYTES_BETWEEN_MAGIC_AND_COMMENT_SIZE as i64,
83
748
                ))?;
84
748
                let cde_start_pos = reader.seek(io::SeekFrom::Start(pos))?;
85
748
                return CentralDirectoryEnd::parse(reader).map(|cde| (cde, cde_start_pos));
86
749M
            }
87
749M
            pos = match pos.checked_sub(1) {
88
749M
                Some(p) => p,
89
0
                None => break,
90
            };
91
        }
92
10.9k
        Err(ZipError::InvalidArchive(
93
10.9k
            "Could not find central directory end",
94
10.9k
        ))
95
11.6k
    }
96
97
11.7k
    pub fn write<T: Write>(&self, writer: &mut T) -> ZipResult<()> {
98
11.7k
        writer.write_u32::<LittleEndian>(CENTRAL_DIRECTORY_END_SIGNATURE)?;
99
11.6k
        writer.write_u16::<LittleEndian>(self.disk_number)?;
100
11.6k
        writer.write_u16::<LittleEndian>(self.disk_with_central_directory)?;
101
11.6k
        writer.write_u16::<LittleEndian>(self.number_of_files_on_this_disk)?;
102
11.6k
        writer.write_u16::<LittleEndian>(self.number_of_files)?;
103
11.6k
        writer.write_u32::<LittleEndian>(self.central_directory_size)?;
104
11.6k
        writer.write_u32::<LittleEndian>(self.central_directory_offset)?;
105
11.6k
        writer.write_u16::<LittleEndian>(self.zip_file_comment.len() as u16)?;
106
11.6k
        writer.write_all(&self.zip_file_comment)?;
107
11.6k
        Ok(())
108
11.7k
    }
109
}
110
111
pub struct Zip64CentralDirectoryEndLocator {
112
    pub disk_with_central_directory: u32,
113
    pub end_of_central_directory_offset: u64,
114
    pub number_of_disks: u32,
115
}
116
117
impl Zip64CentralDirectoryEndLocator {
118
3.07k
    pub fn parse<T: Read>(reader: &mut T) -> ZipResult<Zip64CentralDirectoryEndLocator> {
119
3.07k
        let magic = reader.read_u32::<LittleEndian>()?;
120
3.07k
        if magic != ZIP64_CENTRAL_DIRECTORY_END_LOCATOR_SIGNATURE {
121
2.37k
            return Err(ZipError::InvalidArchive(
122
2.37k
                "Invalid zip64 locator digital signature header",
123
2.37k
            ));
124
697
        }
125
697
        let disk_with_central_directory = reader.read_u32::<LittleEndian>()?;
126
697
        let end_of_central_directory_offset = reader.read_u64::<LittleEndian>()?;
127
697
        let number_of_disks = reader.read_u32::<LittleEndian>()?;
128
129
697
        Ok(Zip64CentralDirectoryEndLocator {
130
697
            disk_with_central_directory,
131
697
            end_of_central_directory_offset,
132
697
            number_of_disks,
133
697
        })
134
3.07k
    }
<zip::spec::Zip64CentralDirectoryEndLocator>::parse::<std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
118
1.90k
    pub fn parse<T: Read>(reader: &mut T) -> ZipResult<Zip64CentralDirectoryEndLocator> {
119
1.90k
        let magic = reader.read_u32::<LittleEndian>()?;
120
1.90k
        if magic != ZIP64_CENTRAL_DIRECTORY_END_LOCATOR_SIGNATURE {
121
1.21k
            return Err(ZipError::InvalidArchive(
122
1.21k
                "Invalid zip64 locator digital signature header",
123
1.21k
            ));
124
686
        }
125
686
        let disk_with_central_directory = reader.read_u32::<LittleEndian>()?;
126
686
        let end_of_central_directory_offset = reader.read_u64::<LittleEndian>()?;
127
686
        let number_of_disks = reader.read_u32::<LittleEndian>()?;
128
129
686
        Ok(Zip64CentralDirectoryEndLocator {
130
686
            disk_with_central_directory,
131
686
            end_of_central_directory_offset,
132
686
            number_of_disks,
133
686
        })
134
1.90k
    }
<zip::spec::Zip64CentralDirectoryEndLocator>::parse::<std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
118
418
    pub fn parse<T: Read>(reader: &mut T) -> ZipResult<Zip64CentralDirectoryEndLocator> {
119
418
        let magic = reader.read_u32::<LittleEndian>()?;
120
418
        if magic != ZIP64_CENTRAL_DIRECTORY_END_LOCATOR_SIGNATURE {
121
407
            return Err(ZipError::InvalidArchive(
122
407
                "Invalid zip64 locator digital signature header",
123
407
            ));
124
11
        }
125
11
        let disk_with_central_directory = reader.read_u32::<LittleEndian>()?;
126
11
        let end_of_central_directory_offset = reader.read_u64::<LittleEndian>()?;
127
11
        let number_of_disks = reader.read_u32::<LittleEndian>()?;
128
129
11
        Ok(Zip64CentralDirectoryEndLocator {
130
11
            disk_with_central_directory,
131
11
            end_of_central_directory_offset,
132
11
            number_of_disks,
133
11
        })
134
418
    }
<zip::spec::Zip64CentralDirectoryEndLocator>::parse::<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>
Line
Count
Source
118
748
    pub fn parse<T: Read>(reader: &mut T) -> ZipResult<Zip64CentralDirectoryEndLocator> {
119
748
        let magic = reader.read_u32::<LittleEndian>()?;
120
748
        if magic != ZIP64_CENTRAL_DIRECTORY_END_LOCATOR_SIGNATURE {
121
748
            return Err(ZipError::InvalidArchive(
122
748
                "Invalid zip64 locator digital signature header",
123
748
            ));
124
0
        }
125
0
        let disk_with_central_directory = reader.read_u32::<LittleEndian>()?;
126
0
        let end_of_central_directory_offset = reader.read_u64::<LittleEndian>()?;
127
0
        let number_of_disks = reader.read_u32::<LittleEndian>()?;
128
129
0
        Ok(Zip64CentralDirectoryEndLocator {
130
0
            disk_with_central_directory,
131
0
            end_of_central_directory_offset,
132
0
            number_of_disks,
133
0
        })
134
748
    }
135
136
0
    pub fn write<T: Write>(&self, writer: &mut T) -> ZipResult<()> {
137
0
        writer.write_u32::<LittleEndian>(ZIP64_CENTRAL_DIRECTORY_END_LOCATOR_SIGNATURE)?;
138
0
        writer.write_u32::<LittleEndian>(self.disk_with_central_directory)?;
139
0
        writer.write_u64::<LittleEndian>(self.end_of_central_directory_offset)?;
140
0
        writer.write_u32::<LittleEndian>(self.number_of_disks)?;
141
0
        Ok(())
142
0
    }
143
}
144
145
pub struct Zip64CentralDirectoryEnd {
146
    pub version_made_by: u16,
147
    pub version_needed_to_extract: u16,
148
    pub disk_number: u32,
149
    pub disk_with_central_directory: u32,
150
    pub number_of_files_on_this_disk: u64,
151
    pub number_of_files: u64,
152
    pub central_directory_size: u64,
153
    pub central_directory_offset: u64,
154
    //pub extensible_data_sector: Vec<u8>, <-- We don't do anything with this at the moment.
155
}
156
157
impl Zip64CentralDirectoryEnd {
158
580
    pub fn find_and_parse<T: Read + io::Seek>(
159
580
        reader: &mut T,
160
580
        nominal_offset: u64,
161
580
        search_upper_bound: u64,
162
580
    ) -> ZipResult<(Zip64CentralDirectoryEnd, u64)> {
163
580
        let mut pos = nominal_offset;
164
165
3.50M
        while pos <= search_upper_bound {
166
3.50M
            reader.seek(io::SeekFrom::Start(pos))?;
167
168
3.50M
            if reader.read_u32::<LittleEndian>()? == ZIP64_CENTRAL_DIRECTORY_END_SIGNATURE {
169
433
                let archive_offset = pos - nominal_offset;
170
171
433
                let _record_size = reader.read_u64::<LittleEndian>()?;
172
                // We would use this value if we did anything with the "zip64 extensible data sector".
173
174
433
                let version_made_by = reader.read_u16::<LittleEndian>()?;
175
433
                let version_needed_to_extract = reader.read_u16::<LittleEndian>()?;
176
433
                let disk_number = reader.read_u32::<LittleEndian>()?;
177
433
                let disk_with_central_directory = reader.read_u32::<LittleEndian>()?;
178
433
                let number_of_files_on_this_disk = reader.read_u64::<LittleEndian>()?;
179
433
                let number_of_files = reader.read_u64::<LittleEndian>()?;
180
433
                let central_directory_size = reader.read_u64::<LittleEndian>()?;
181
433
                let central_directory_offset = reader.read_u64::<LittleEndian>()?;
182
183
433
                return Ok((
184
433
                    Zip64CentralDirectoryEnd {
185
433
                        version_made_by,
186
433
                        version_needed_to_extract,
187
433
                        disk_number,
188
433
                        disk_with_central_directory,
189
433
                        number_of_files_on_this_disk,
190
433
                        number_of_files,
191
433
                        central_directory_size,
192
433
                        central_directory_offset,
193
433
                    },
194
433
                    archive_offset,
195
433
                ));
196
3.50M
            }
197
198
3.50M
            pos += 1;
199
        }
200
201
147
        Err(ZipError::InvalidArchive(
202
147
            "Could not find ZIP64 central directory end",
203
147
        ))
204
580
    }
<zip::spec::Zip64CentralDirectoryEnd>::find_and_parse::<std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
158
569
    pub fn find_and_parse<T: Read + io::Seek>(
159
569
        reader: &mut T,
160
569
        nominal_offset: u64,
161
569
        search_upper_bound: u64,
162
569
    ) -> ZipResult<(Zip64CentralDirectoryEnd, u64)> {
163
569
        let mut pos = nominal_offset;
164
165
2.18M
        while pos <= search_upper_bound {
166
2.18M
            reader.seek(io::SeekFrom::Start(pos))?;
167
168
2.18M
            if reader.read_u32::<LittleEndian>()? == ZIP64_CENTRAL_DIRECTORY_END_SIGNATURE {
169
423
                let archive_offset = pos - nominal_offset;
170
171
423
                let _record_size = reader.read_u64::<LittleEndian>()?;
172
                // We would use this value if we did anything with the "zip64 extensible data sector".
173
174
423
                let version_made_by = reader.read_u16::<LittleEndian>()?;
175
423
                let version_needed_to_extract = reader.read_u16::<LittleEndian>()?;
176
423
                let disk_number = reader.read_u32::<LittleEndian>()?;
177
423
                let disk_with_central_directory = reader.read_u32::<LittleEndian>()?;
178
423
                let number_of_files_on_this_disk = reader.read_u64::<LittleEndian>()?;
179
423
                let number_of_files = reader.read_u64::<LittleEndian>()?;
180
423
                let central_directory_size = reader.read_u64::<LittleEndian>()?;
181
423
                let central_directory_offset = reader.read_u64::<LittleEndian>()?;
182
183
423
                return Ok((
184
423
                    Zip64CentralDirectoryEnd {
185
423
                        version_made_by,
186
423
                        version_needed_to_extract,
187
423
                        disk_number,
188
423
                        disk_with_central_directory,
189
423
                        number_of_files_on_this_disk,
190
423
                        number_of_files,
191
423
                        central_directory_size,
192
423
                        central_directory_offset,
193
423
                    },
194
423
                    archive_offset,
195
423
                ));
196
2.18M
            }
197
198
2.18M
            pos += 1;
199
        }
200
201
146
        Err(ZipError::InvalidArchive(
202
146
            "Could not find ZIP64 central directory end",
203
146
        ))
204
569
    }
<zip::spec::Zip64CentralDirectoryEnd>::find_and_parse::<std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
158
11
    pub fn find_and_parse<T: Read + io::Seek>(
159
11
        reader: &mut T,
160
11
        nominal_offset: u64,
161
11
        search_upper_bound: u64,
162
11
    ) -> ZipResult<(Zip64CentralDirectoryEnd, u64)> {
163
11
        let mut pos = nominal_offset;
164
165
1.32M
        while pos <= search_upper_bound {
166
1.32M
            reader.seek(io::SeekFrom::Start(pos))?;
167
168
1.32M
            if reader.read_u32::<LittleEndian>()? == ZIP64_CENTRAL_DIRECTORY_END_SIGNATURE {
169
10
                let archive_offset = pos - nominal_offset;
170
171
10
                let _record_size = reader.read_u64::<LittleEndian>()?;
172
                // We would use this value if we did anything with the "zip64 extensible data sector".
173
174
10
                let version_made_by = reader.read_u16::<LittleEndian>()?;
175
10
                let version_needed_to_extract = reader.read_u16::<LittleEndian>()?;
176
10
                let disk_number = reader.read_u32::<LittleEndian>()?;
177
10
                let disk_with_central_directory = reader.read_u32::<LittleEndian>()?;
178
10
                let number_of_files_on_this_disk = reader.read_u64::<LittleEndian>()?;
179
10
                let number_of_files = reader.read_u64::<LittleEndian>()?;
180
10
                let central_directory_size = reader.read_u64::<LittleEndian>()?;
181
10
                let central_directory_offset = reader.read_u64::<LittleEndian>()?;
182
183
10
                return Ok((
184
10
                    Zip64CentralDirectoryEnd {
185
10
                        version_made_by,
186
10
                        version_needed_to_extract,
187
10
                        disk_number,
188
10
                        disk_with_central_directory,
189
10
                        number_of_files_on_this_disk,
190
10
                        number_of_files,
191
10
                        central_directory_size,
192
10
                        central_directory_offset,
193
10
                    },
194
10
                    archive_offset,
195
10
                ));
196
1.32M
            }
197
198
1.32M
            pos += 1;
199
        }
200
201
1
        Err(ZipError::InvalidArchive(
202
1
            "Could not find ZIP64 central directory end",
203
1
        ))
204
11
    }
Unexecuted instantiation: <zip::spec::Zip64CentralDirectoryEnd>::find_and_parse::<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>
205
206
0
    pub fn write<T: Write>(&self, writer: &mut T) -> ZipResult<()> {
207
0
        writer.write_u32::<LittleEndian>(ZIP64_CENTRAL_DIRECTORY_END_SIGNATURE)?;
208
0
        writer.write_u64::<LittleEndian>(44)?; // record size
209
0
        writer.write_u16::<LittleEndian>(self.version_made_by)?;
210
0
        writer.write_u16::<LittleEndian>(self.version_needed_to_extract)?;
211
0
        writer.write_u32::<LittleEndian>(self.disk_number)?;
212
0
        writer.write_u32::<LittleEndian>(self.disk_with_central_directory)?;
213
0
        writer.write_u64::<LittleEndian>(self.number_of_files_on_this_disk)?;
214
0
        writer.write_u64::<LittleEndian>(self.number_of_files)?;
215
0
        writer.write_u64::<LittleEndian>(self.central_directory_size)?;
216
0
        writer.write_u64::<LittleEndian>(self.central_directory_offset)?;
217
0
        Ok(())
218
0
    }
219
}