@@ -87,3 +87,240 @@ impl TryFrom<&[u8]> for FileHeader {
87
87
Ok ( file_header)
88
88
}
89
89
}
90
+
91
+ #[ cfg( test) ]
92
+ mod tests {
93
+ use super :: * ;
94
+
95
+ mod helpers {
96
+ pub const VALID_HEADER : [ u8 ; 32 ] = [
97
+ 0x52 , 0x4D , 0x41 , 0x4E , 0x02 , 0x00 , 0x00 , 0x02 , 0x1C , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
98
+ 0x00 , 0x00 , 0xD2 , 0x17 , 0xC3 , 0xEF , 0xAB , 0x4A , 0x9C , 0x2B , 0x60 , 0xA4 , 0xD0 , 0x01 ,
99
+ 0x00 , 0x00 , 0x00 , 0x00 ,
100
+ ] ;
101
+
102
+ macro_rules! assert_error {
103
+ ( $buf: ident, $error: ident) => {
104
+ let Err ( error) = crate :: FileHeader :: try_from( & $buf[ ..] ) else {
105
+ panic!( "did not throw an error" ) ;
106
+ } ;
107
+ let crate :: error:: ManifestError :: $error( ..) = error else {
108
+ panic!( "some other error was thrown" ) ;
109
+ } ;
110
+ } ;
111
+ }
112
+
113
+ pub ( crate ) use assert_error;
114
+ }
115
+
116
+ #[ test]
117
+ fn should_parse_when_valid_header ( ) {
118
+ if let Err ( error) = FileHeader :: try_from ( & helpers:: VALID_HEADER [ ..] ) {
119
+ panic ! (
120
+ "there was an error when parsing header, header: {:?}" ,
121
+ error
122
+ ) ;
123
+ } ;
124
+ }
125
+
126
+ #[ test]
127
+ fn should_have_correct_values_when_valid_header ( ) {
128
+ let header = FileHeader :: try_from ( & helpers:: VALID_HEADER [ ..] ) . unwrap ( ) ;
129
+
130
+ assert_eq ! ( header. magic, 0x4E414D52 , "magic bytes did not match" ) ;
131
+ assert_eq ! ( header. major, 2 , "major version did not match" ) ;
132
+ assert_eq ! ( header. minor, 0 , "minor version did not match" ) ;
133
+ assert_eq ! ( header. flags, 512 , "flags did not match" ) ;
134
+ assert_eq ! ( header. offset, 28 , "offset did not match" ) ;
135
+ assert_eq ! ( header. compressed_size, 0 , "compressed size did not match" ) ;
136
+ assert_eq ! (
137
+ header. manifest_id, 3142468742320166866 ,
138
+ "manifest id did not match"
139
+ ) ;
140
+ assert_eq ! (
141
+ header. uncompressed_size, 30450784 ,
142
+ "unompressed size did not match"
143
+ ) ;
144
+ }
145
+
146
+ #[ test]
147
+ fn should_throw_correct_errors_when_eof ( ) {
148
+ // EOF when reading magic bytes
149
+ let error = FileHeader :: try_from ( & helpers:: VALID_HEADER [ ..3 ] )
150
+ . err ( )
151
+ . expect ( "did not throw an error on missing bytes" ) ;
152
+ match error {
153
+ crate :: error:: ManifestError :: ReadBytesError ( _) => ( ) ,
154
+ _ => panic ! ( "invalid ManifestError error when eof" ) ,
155
+ } ;
156
+
157
+ // EOF when reading major
158
+ let error = FileHeader :: try_from ( & helpers:: VALID_HEADER [ ..4 ] )
159
+ . err ( )
160
+ . expect ( "did not throw an error on missing bytes" ) ;
161
+ match error {
162
+ crate :: error:: ManifestError :: ReadBytesError ( _) => ( ) ,
163
+ _ => panic ! ( "invalid ManifestError error when eof" ) ,
164
+ } ;
165
+
166
+ // EOF when reading minor
167
+ let error = FileHeader :: try_from ( & helpers:: VALID_HEADER [ ..5 ] )
168
+ . err ( )
169
+ . expect ( "did not throw an error on missing bytes" ) ;
170
+ match error {
171
+ crate :: error:: ManifestError :: ReadBytesError ( _) => ( ) ,
172
+ _ => panic ! ( "invalid ManifestError error when eof" ) ,
173
+ } ;
174
+
175
+ // EOF when reading flags
176
+ let error = FileHeader :: try_from ( & helpers:: VALID_HEADER [ ..7 ] )
177
+ . err ( )
178
+ . expect ( "did not throw an error on missing bytes" ) ;
179
+ match error {
180
+ crate :: error:: ManifestError :: ReadBytesError ( _) => ( ) ,
181
+ _ => panic ! ( "invalid ManifestError error when eof" ) ,
182
+ } ;
183
+
184
+ // EOF when reading offset
185
+ let error = FileHeader :: try_from ( & helpers:: VALID_HEADER [ ..11 ] )
186
+ . err ( )
187
+ . expect ( "did not throw an error on missing bytes" ) ;
188
+ match error {
189
+ crate :: error:: ManifestError :: ReadBytesError ( _) => ( ) ,
190
+ _ => panic ! ( "invalid ManifestError error when eof" ) ,
191
+ } ;
192
+
193
+ // it should be impossible for reading to fail at this point, because
194
+ // offset must be greater than 28 and and less then file size, which
195
+ // in turn ensures that the file size is at least 28 bytes
196
+ }
197
+
198
+ #[ test]
199
+ fn should_error_when_invalid_magic_bytes ( ) {
200
+ let buf = [ & [ 0x53 ] , & helpers:: VALID_HEADER [ 1 ..] ] . concat ( ) ;
201
+
202
+ helpers:: assert_error!( buf, InvalidMagicBytes ) ;
203
+ }
204
+
205
+ #[ test]
206
+ fn should_error_when_invalid_major ( ) {
207
+ let buf = [
208
+ & helpers:: VALID_HEADER [ ..4 ] ,
209
+ & [ 0x01 ] ,
210
+ & helpers:: VALID_HEADER [ 5 ..] ,
211
+ ]
212
+ . concat ( ) ;
213
+
214
+ #[ cfg( not( feature = "version_error" ) ) ]
215
+ if let Err ( _) = FileHeader :: try_from ( & buf[ ..] ) {
216
+ panic ! ( "error was thrown" ) ;
217
+ }
218
+
219
+ #[ cfg( feature = "version_error" ) ]
220
+ helpers:: assert_error!( buf, InvalidMajor ) ;
221
+ }
222
+
223
+ #[ test]
224
+ fn should_error_when_invalid_minor ( ) {
225
+ let buf = [
226
+ & helpers:: VALID_HEADER [ ..5 ] ,
227
+ & [ 0x01 ] ,
228
+ & helpers:: VALID_HEADER [ 6 ..] ,
229
+ ]
230
+ . concat ( ) ;
231
+
232
+ #[ cfg( not( feature = "version_error" ) ) ]
233
+ if let Err ( _) = FileHeader :: try_from ( & buf[ ..] ) {
234
+ panic ! ( "error was thrown" )
235
+ }
236
+
237
+ #[ cfg( feature = "version_error" ) ]
238
+ helpers:: assert_error!( buf, InvalidMinor ) ;
239
+ }
240
+
241
+ #[ test]
242
+ fn should_error_when_offset_too_small ( ) {
243
+ // too small
244
+ let buf = [
245
+ & helpers:: VALID_HEADER [ ..8 ] ,
246
+ & 0u32 . to_le_bytes ( ) ,
247
+ & helpers:: VALID_HEADER [ 12 ..] ,
248
+ ]
249
+ . concat ( ) ;
250
+
251
+ helpers:: assert_error!( buf, InvalidOffset ) ;
252
+
253
+ // slightly too small
254
+ let buf = [
255
+ & helpers:: VALID_HEADER [ ..8 ] ,
256
+ & 27u32 . to_le_bytes ( ) ,
257
+ & helpers:: VALID_HEADER [ 12 ..] ,
258
+ ]
259
+ . concat ( ) ;
260
+
261
+ helpers:: assert_error!( buf, InvalidOffset ) ;
262
+ }
263
+
264
+ #[ test]
265
+ fn should_error_when_offset_too_large ( ) {
266
+ // slightly too large
267
+ let size = u32:: try_from ( helpers:: VALID_HEADER . len ( ) ) . unwrap ( ) ;
268
+ let buf = [
269
+ & helpers:: VALID_HEADER [ ..8 ] ,
270
+ & size. to_le_bytes ( ) ,
271
+ & helpers:: VALID_HEADER [ 12 ..] ,
272
+ ]
273
+ . concat ( ) ;
274
+
275
+ helpers:: assert_error!( buf, InvalidOffset ) ;
276
+
277
+ // too large
278
+ let buf = [
279
+ & helpers:: VALID_HEADER [ ..8 ] ,
280
+ & u32:: MAX . to_le_bytes ( ) ,
281
+ & helpers:: VALID_HEADER [ 12 ..] ,
282
+ ]
283
+ . concat ( ) ;
284
+
285
+ helpers:: assert_error!( buf, InvalidOffset ) ;
286
+ }
287
+
288
+ #[ test]
289
+ fn should_error_when_compressed_size_too_large ( ) {
290
+ // slightly too large
291
+ let size = u32:: try_from ( helpers:: VALID_HEADER . len ( ) ) . unwrap ( ) ;
292
+ let buf = [
293
+ & helpers:: VALID_HEADER [ ..12 ] ,
294
+ & ( size - 27 ) . to_le_bytes ( ) ,
295
+ & helpers:: VALID_HEADER [ 16 ..] ,
296
+ ]
297
+ . concat ( ) ;
298
+
299
+ helpers:: assert_error!( buf, CompressedSizeTooLarge ) ;
300
+
301
+ // too large
302
+ let buf = [
303
+ & helpers:: VALID_HEADER [ ..12 ] ,
304
+ & u32:: MAX . to_le_bytes ( ) ,
305
+ & helpers:: VALID_HEADER [ 16 ..] ,
306
+ ]
307
+ . concat ( ) ;
308
+
309
+ helpers:: assert_error!( buf, CompressedSizeTooLarge ) ;
310
+ }
311
+
312
+ #[ test]
313
+ fn should_error_when_compressed_size_and_offset_too_large ( ) {
314
+ let offset = 28u32 ;
315
+ let size = u32:: try_from ( helpers:: VALID_HEADER . len ( ) ) . unwrap ( ) ;
316
+ let buf = [
317
+ & helpers:: VALID_HEADER [ ..8 ] ,
318
+ & offset. to_le_bytes ( ) ,
319
+ & ( size - offset + 1 ) . to_le_bytes ( ) ,
320
+ & helpers:: VALID_HEADER [ 16 ..] ,
321
+ ]
322
+ . concat ( ) ;
323
+
324
+ helpers:: assert_error!( buf, CompressedSizeTooLarge ) ;
325
+ }
326
+ }
0 commit comments