@@ -38,17 +38,6 @@ pub fn read_fv_header(fv_data: &[u8]) -> Option<FirmwareVolumeHeader> {
38
38
Some ( header)
39
39
}
40
40
41
- // Validate Ffs File header
42
- pub fn validate_ffs_file_header ( header : FfsFileHeader ) -> bool {
43
- // Do the sanity check for Ffs header.
44
- // Verify the header integrity,
45
- //
46
- if !header. validate_checksum ( ) {
47
- return false ;
48
- }
49
- true
50
- }
51
-
52
41
pub fn get_image_from_fv (
53
42
fv_data : & [ u8 ] ,
54
43
fv_file_type : FvFileType ,
@@ -58,10 +47,10 @@ pub fn get_image_from_fv(
58
47
59
48
let files = Files :: parse ( fv_data, fv_header. header_length as usize ) ?;
60
49
for ( file_header, file_data) in files {
61
- if !validate_ffs_file_header ( file_header) {
50
+ if !file_header. validate ( ) {
62
51
return None ;
63
52
}
64
- if file_header. r#type == fv_file_type {
53
+ if file_header. r#type ( ) == fv_file_type {
65
54
return get_image_from_sections ( file_data, section_type) ;
66
55
}
67
56
}
@@ -78,10 +67,10 @@ pub fn get_file_from_fv(
78
67
79
68
let files = Files :: parse ( fv_data, fv_header. header_length as usize ) ?;
80
69
for ( file_header, file_data) in files {
81
- if !validate_ffs_file_header ( file_header) {
70
+ if !file_header. validate ( ) {
82
71
return None ;
83
72
}
84
- if file_header. r#type == fv_file_type && & file_header. name == file_name. as_bytes ( ) {
73
+ if file_header. r#type ( ) == fv_file_type && file_header. name ( ) == file_name. as_bytes ( ) {
85
74
return Some ( file_data) ;
86
75
}
87
76
}
@@ -93,14 +82,28 @@ fn get_image_from_sections(sections_data: &[u8], section_type: SectionType) -> O
93
82
let sections = Sections :: parse ( sections_data, 0 ) ?;
94
83
95
84
for ( section_header, section_data) in sections {
96
- if section_header. r#type == section_type {
85
+ if section_header. r#type ( ) == section_type {
97
86
return Some ( section_data) ;
98
87
}
99
88
}
100
89
101
90
None
102
91
}
103
92
93
+ enum CommonSectionHeaderType {
94
+ Header ( CommonSectionHeader ) ,
95
+ Header2 ( CommonSectionHeader2 ) ,
96
+ }
97
+
98
+ impl CommonSectionHeaderType {
99
+ fn r#type ( & self ) -> FvFileType {
100
+ match self {
101
+ Self :: Header ( header) => header. r#type ,
102
+ Self :: Header2 ( header2) => header2. r#type ,
103
+ }
104
+ }
105
+ }
106
+
104
107
struct Sections < ' a > {
105
108
buffer : & ' a [ u8 ] ,
106
109
}
@@ -118,17 +121,32 @@ impl<'a> Sections<'a> {
118
121
}
119
122
120
123
impl < ' a > Iterator for Sections < ' a > {
121
- type Item = ( CommonSectionHeader , & ' a [ u8 ] ) ;
124
+ type Item = ( CommonSectionHeaderType , & ' a [ u8 ] ) ;
122
125
123
126
fn next ( & mut self ) -> Option < Self :: Item > {
124
- const HEADER_SIZE : usize = core:: mem:: size_of :: < CommonSectionHeader > ( ) ;
125
127
let header: CommonSectionHeader = self . buffer . pread ( 0 ) . ok ( ) ?;
126
- let section_size = header. size [ 0 ] as usize
127
- + ( ( header. size [ 1 ] as usize ) << 8 )
128
- + ( ( header. size [ 2 ] as usize ) << 16 ) ;
129
- section_size. checked_sub ( HEADER_SIZE ) ?;
128
+ let is_large_section = header. size == [ 0xff , 0xff , 0xff ] ;
129
+
130
+ let ( section_size, section_header, header_size) = if is_large_section {
131
+ let header2: CommonSectionHeader2 = self . buffer . pread ( 0 ) . ok ( ) ?;
132
+ (
133
+ header2. extended_size as usize ,
134
+ CommonSectionHeaderType :: Header2 ( header2) ,
135
+ core:: mem:: size_of :: < CommonSectionHeader2 > ( ) ,
136
+ )
137
+ } else {
138
+ (
139
+ header. size [ 0 ] as usize
140
+ + ( ( header. size [ 1 ] as usize ) << 8 )
141
+ + ( ( header. size [ 2 ] as usize ) << 16 ) ,
142
+ CommonSectionHeaderType :: Header ( header) ,
143
+ core:: mem:: size_of :: < CommonSectionHeader > ( ) ,
144
+ )
145
+ } ;
146
+
147
+ section_size. checked_sub ( header_size) ?;
130
148
self . buffer . len ( ) . checked_sub ( section_size) ?;
131
- let buf = & self . buffer [ HEADER_SIZE ..section_size] ;
149
+ let buf = & self . buffer [ header_size ..section_size] ;
132
150
133
151
// Align to 4 bytes.
134
152
let section_size = ( section_size + 3 ) & !3 ;
@@ -138,7 +156,39 @@ impl<'a> Iterator for Sections<'a> {
138
156
self . buffer = & self . buffer [ 0 ..0 ] ;
139
157
}
140
158
141
- Some ( ( header, buf) )
159
+ Some ( ( section_header, buf) )
160
+ }
161
+ }
162
+
163
+ enum FfsFileHeaderType {
164
+ Header ( FfsFileHeader ) ,
165
+ Header2 ( FfsFileHeader2 ) ,
166
+ }
167
+
168
+ impl FfsFileHeaderType {
169
+ fn r#type ( & self ) -> FvFileType {
170
+ match self {
171
+ FfsFileHeaderType :: Header ( header) => header. r#type ,
172
+ FfsFileHeaderType :: Header2 ( header2) => header2. r#type ,
173
+ }
174
+ }
175
+
176
+ fn name ( & self ) -> & [ u8 ] {
177
+ match self {
178
+ FfsFileHeaderType :: Header ( header) => & header. name ,
179
+ FfsFileHeaderType :: Header2 ( header2) => & header2. name ,
180
+ }
181
+ }
182
+
183
+ // Validate Ffs File header
184
+ fn validate ( & self ) -> bool {
185
+ // Do the sanity check for Ffs header.
186
+ // Verify the header integrity,
187
+ //
188
+ match self {
189
+ FfsFileHeaderType :: Header ( header) => ffs_header_validate_checksum ( header. as_bytes ( ) ) ,
190
+ FfsFileHeaderType :: Header2 ( header2) => ffs_header_validate_checksum ( header2. as_bytes ( ) ) ,
191
+ }
142
192
}
143
193
}
144
194
@@ -159,18 +209,32 @@ impl<'a> Files<'a> {
159
209
}
160
210
161
211
impl < ' a > Iterator for Files < ' a > {
162
- type Item = ( FfsFileHeader , & ' a [ u8 ] ) ;
212
+ type Item = ( FfsFileHeaderType , & ' a [ u8 ] ) ;
163
213
164
214
fn next ( & mut self ) -> Option < Self :: Item > {
165
- const HEADER_SIZE : usize = core:: mem:: size_of :: < FfsFileHeader > ( ) ;
166
-
167
215
let header: FfsFileHeader = self . buffer . pread ( 0 ) . ok ( ) ?;
168
- let data_size = header. size [ 0 ] as usize
169
- + ( ( header. size [ 1 ] as usize ) << 8 )
170
- + ( ( header. size [ 2 ] as usize ) << 16 ) ;
171
- data_size. checked_sub ( HEADER_SIZE ) ?;
216
+ let is_large_file = header. attributes & FFS_ATTRIB_LARGE_FILE != 0 ;
217
+
218
+ let ( data_size, ffs_header, header_size) = if is_large_file {
219
+ let header2: FfsFileHeader2 = self . buffer . pread ( 0 ) . ok ( ) ?;
220
+ (
221
+ header2. extended_size as usize ,
222
+ FfsFileHeaderType :: Header2 ( header2) ,
223
+ core:: mem:: size_of :: < FfsFileHeader2 > ( ) ,
224
+ )
225
+ } else {
226
+ (
227
+ header. size [ 0 ] as usize
228
+ + ( ( header. size [ 1 ] as usize ) << 8 )
229
+ + ( ( header. size [ 2 ] as usize ) << 16 ) ,
230
+ FfsFileHeaderType :: Header ( header) ,
231
+ core:: mem:: size_of :: < FfsFileHeader > ( ) ,
232
+ )
233
+ } ;
234
+
235
+ data_size. checked_sub ( header_size) ?;
172
236
self . buffer . len ( ) . checked_sub ( data_size) ?;
173
- let buf = & self . buffer [ HEADER_SIZE ..data_size] ;
237
+ let buf = & self . buffer [ header_size ..data_size] ;
174
238
175
239
// Align to 8 bytes.
176
240
let data_size = ( data_size + 7 ) & !7 ;
@@ -180,7 +244,7 @@ impl<'a> Iterator for Files<'a> {
180
244
self . buffer = & self . buffer [ 0 ..0 ] ;
181
245
}
182
246
183
- Some ( ( header , buf) )
247
+ Some ( ( ffs_header , buf) )
184
248
}
185
249
}
186
250
0 commit comments