| // Copyright 2020 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #![cfg(test)] |
| |
| use { |
| assert_matches::assert_matches, |
| fidl_fuchsia_io as fio, |
| fuchsia_archive::{ChunkType, Error, Reader, DIR_CHUNK_TYPE, DIR_NAMES_CHUNK_TYPE}, |
| std::{fs::File, path::Path}, |
| }; |
| |
| const ALL_ZEROES_CHUNK_TYPE: ChunkType = [0u8; 8]; |
| |
| // Creates a test fn named after the first parameter that: |
| // 1. opens a FAR file named after the first parameter |
| // 2. calls fuchsia_archive::Reader::new on the file |
| // 3. asserts that the new() result matches the second parameter |
| // And also an async version of the same test using fuchsia_archive::AsyncReader. |
| macro_rules! tests { |
| ( $( $fn:ident => $err:pat $(if $guard:expr)? , )+ ) => { |
| $( |
| #[test] |
| fn $fn() { |
| let mut filename = stringify!($fn).replace("_", "-"); |
| filename.push_str(".far"); |
| let file = File::open(Path::new("/pkg/data/invalid-fars").join(filename)).unwrap(); |
| assert_matches!(Reader::new(file), $err $(if $guard)?); |
| } |
| )+ |
| |
| mod async_tests { |
| use { |
| super::*, |
| fuchsia_async as fasync, |
| fuchsia_archive::AsyncReader, |
| assert_matches::assert_matches, |
| }; |
| |
| $( |
| #[fasync::run_singlethreaded(test)] |
| async fn $fn() { |
| let mut filename = stringify!($fn).replace("_", "-"); |
| filename.push_str(".far"); |
| let path = Path::new("/pkg/data/invalid-fars").join(filename); |
| let file = fuchsia_fs::file::open_in_namespace( |
| path.to_str().unwrap(), |
| fio::OpenFlags::RIGHT_READABLE, |
| ) |
| .unwrap(); |
| let reader = fuchsia_fs::file::AsyncFile::from_proxy(file); |
| assert_matches!(AsyncReader::new(reader).await, $err $(if $guard)?); |
| } |
| )+ |
| } |
| }; |
| } |
| |
| tests! { |
| invalid_magic_bytes => Err(Error::InvalidMagic([0, 0, 0, 0, 0, 0, 0, 0])), |
| |
| index_entries_length_not_a_multiple_of_24_bytes => Err(Error::InvalidIndexEntriesLen(49)), |
| |
| directory_names_index_entry_before_directory_index_entry => |
| Err(Error::IndexEntriesOutOfOrder { prev: DIR_NAMES_CHUNK_TYPE, next: DIR_CHUNK_TYPE }), |
| |
| two_directory_index_entries => |
| Err(Error::IndexEntriesOutOfOrder { prev: DIR_CHUNK_TYPE, next: DIR_CHUNK_TYPE }), |
| |
| two_directory_names_index_entries => |
| Err(Error::IndexEntriesOutOfOrder { |
| prev: DIR_NAMES_CHUNK_TYPE, |
| next: DIR_NAMES_CHUNK_TYPE |
| }), |
| |
| duplicate_index_entries_of_unknown_type => |
| Err(Error::IndexEntriesOutOfOrder { |
| prev: ALL_ZEROES_CHUNK_TYPE, |
| next: ALL_ZEROES_CHUNK_TYPE |
| }), |
| |
| no_index_entries => Err(Error::MissingDirectoryChunkIndexEntry), |
| |
| no_directory_index_entry => Err(Error::MissingDirectoryChunkIndexEntry), |
| |
| no_directory_names_index_entry => Err(Error::MissingDirectoryNamesChunkIndexEntry), |
| |
| directory_chunk_length_not_a_multiple_of_32_bytes => Err(Error::InvalidDirectoryChunkLen(40)), |
| |
| directory_chunk_not_tightly_packed => |
| Err(Error::InvalidChunkOffset { chunk_type: DIR_CHUNK_TYPE, expected: 64, actual: 72 }), |
| |
| path_data_offset_too_large => |
| Err(Error::PathDataOffsetTooLarge { entry_index: 0, offset: 9, chunk_size: 8 }), |
| |
| path_data_length_too_large => |
| Err(Error::PathDataLengthTooLarge { entry_index: 0, offset: 0, length: 9, chunk_size: 8 }), |
| |
| directory_entries_not_sorted => |
| Err(Error::DirectoryEntriesOutOfOrder { entry_index: 1, name, previous_name}) |
| if name == b"a" && previous_name == b"b", |
| |
| directory_entries_with_same_name => |
| Err(Error::DirectoryEntriesOutOfOrder { entry_index: 1, name, previous_name}) |
| if name == b"a" && previous_name == b"a", |
| |
| directory_names_chunk_length_not_a_multiple_of_8_bytes => |
| Err(Error::InvalidDirectoryNamesChunkLen(1)), |
| |
| directory_names_chunk_not_tightly_packed => |
| Err(Error::InvalidChunkOffset { |
| chunk_type: DIR_NAMES_CHUNK_TYPE, |
| expected: 96, |
| actual: 104 |
| }), |
| |
| directory_names_chunk_before_directory_chunk => |
| Err(Error::InvalidChunkOffset { chunk_type: DIR_CHUNK_TYPE, expected: 64, actual: 72 }), |
| |
| directory_names_chunk_overlaps_directory_chunk => |
| Err(Error::InvalidChunkOffset { |
| chunk_type: DIR_NAMES_CHUNK_TYPE, |
| expected: 96, |
| actual: 88 |
| }), |
| |
| zero_length_name => Err(Error::ZeroLengthName), |
| |
| name_with_null_character => Err(Error::NameContainsNull(name)) if name == b"\0", |
| |
| name_with_leading_slash => Err(Error::NameStartsWithSlash(name)) if name == b"/a", |
| |
| name_with_trailing_slash => Err(Error::NameEndsWithSlash(name)) if name == b"a/", |
| |
| name_with_empty_segment => |
| Err(Error::NameContainsEmptySegment(name)) if name == b"a//a", |
| |
| name_with_dot_segment => |
| Err(Error::NameContainsDotSegment(name)) if name == b"a/./a", |
| |
| name_with_dot_dot_segment => |
| Err(Error::NameContainsDotDotSegment(name)) if name == b"a/../a", |
| |
| content_chunk_starts_early => |
| Err(Error::InvalidContentChunkOffset{name, expected: 4096, actual: 4095}) |
| if name == b"a", |
| |
| content_chunk_starts_late => |
| Err(Error::InvalidContentChunkOffset{name, expected: 4096, actual: 4097}) |
| if name == b"a", |
| |
| second_content_chunk_starts_early => |
| Err(Error::InvalidContentChunkOffset{name, expected: 8192, actual: 8191}) |
| if name == b"b", |
| |
| second_content_chunk_starts_late => |
| Err(Error::InvalidContentChunkOffset{name, expected: 8192, actual: 8193}) |
| if name == b"b", |
| |
| content_chunk_not_zero_padded => |
| Err(Error::ContentChunkBeyondArchive{name, lower_bound: 8192, archive_size: 4097}) |
| if name == b"a", |
| |
| content_chunk_overlap => |
| Err(Error::InvalidContentChunkOffset{name, expected: 12288, actual: 8192}) |
| if name == b"b", |
| |
| content_chunk_not_tightly_packed => |
| Err(Error::InvalidContentChunkOffset{name, expected: 4096, actual: 8192}) |
| if name == b"a", |
| |
| content_chunk_offset_past_end_of_file => |
| Err(Error::ContentChunkBeyondArchive{ |
| name, |
| lower_bound: 4096, |
| archive_size: 104}) |
| if name == b"a", |
| } |