Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / utility / safe_browsing / mac / udif_unittest.cc
blob6afb9d25f2b4553eabc217fd12ba3a510ee5b951
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/utility/safe_browsing/mac/udif.h"
7 #include <hfs/hfs_format.h>
8 #include <libkern/OSByteOrder.h>
10 #include "base/files/file.h"
11 #include "base/strings/stringprintf.h"
12 #include "chrome/utility/safe_browsing/mac/dmg_test_utils.h"
13 #include "chrome/utility/safe_browsing/mac/read_stream.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 namespace safe_browsing {
17 namespace dmg {
18 namespace {
20 const char* kGPTExpectedPartitions[] = {
21 "MBR",
22 "Primary GPT Header",
23 "Primary GPT Tabler",
24 "Apple_Free",
25 "Apple_HFS",
26 "Apple_Free",
27 "Backup GPT Table",
28 "Backup GPT Header",
29 nullptr,
32 const char* kNoPartitionMap[] = {
33 "Apple_HFS",
34 nullptr,
37 const char* kAPMExpectedPartitions[] = {
38 "DDM",
39 "Apple_partition_map",
40 "Apple_HFS",
41 "Apple_Free",
42 nullptr,
45 struct UDIFTestCase {
46 enum ExpectedResults : uint16_t {
47 ALL_FAIL = 0,
48 UDIF_PARSE = 1 << 1,
49 GET_HFS_STREAM = 1 << 2,
50 READ_UDIF_DATA = 1 << 3,
52 ALL_PASS = ~static_cast<uint16_t>(0),
55 // The disk image file to open.
56 const char* file_name;
58 // The NULL-terminated C array of expected partition types.
59 const char** expected_partitions;
61 // A bitmask of ExpectedResults. As the parser currently only supports
62 // certain UDIF features, this is used to properly test expectations.
63 int expected_results;
65 // Generates a human-friendly name for the parameterized test.
66 static std::string GetTestName(
67 const testing::TestParamInfo<UDIFTestCase>& test) {
68 std::string file = test.param.file_name;
69 return file.substr(0, file.find('.'));
73 class UDIFParserTest : public testing::TestWithParam<UDIFTestCase> {
74 protected:
75 void RunReadAllTest(size_t buffer_size) {
76 const UDIFTestCase& test_case = GetParam();
77 if (!(test_case.expected_results & UDIFTestCase::READ_UDIF_DATA)) {
78 return;
81 base::File file;
82 ASSERT_NO_FATAL_FAILURE(test::GetTestFile(test_case.file_name, &file));
84 safe_browsing::dmg::FileReadStream file_stream(file.GetPlatformFile());
85 safe_browsing::dmg::UDIFParser udif(&file_stream);
86 ASSERT_TRUE(udif.Parse());
88 std::vector<uint8_t> buffer(buffer_size, 0);
90 for (size_t i = 0; i < udif.GetNumberOfPartitions(); ++i) {
91 SCOPED_TRACE(base::StringPrintf("partition %zu", i));
93 size_t total_size = udif.GetPartitionSize(i);
94 size_t total_bytes_read = 0;
95 scoped_ptr<ReadStream> stream = udif.GetPartitionReadStream(i);
97 bool success = false;
98 do {
99 size_t bytes_read = 0;
100 success = stream->Read(&buffer[0], buffer.size(), &bytes_read);
101 total_bytes_read += bytes_read;
102 EXPECT_TRUE(success);
103 EXPECT_TRUE(bytes_read == buffer_size ||
104 total_bytes_read == total_size)
105 << "bytes_read = " << bytes_read;
106 } while (total_bytes_read < total_size && success);
111 TEST_P(UDIFParserTest, ParseUDIF) {
112 const UDIFTestCase& test_case = GetParam();
114 base::File file;
115 ASSERT_NO_FATAL_FAILURE(test::GetTestFile(test_case.file_name, &file));
117 safe_browsing::dmg::FileReadStream file_stream(file.GetPlatformFile());
118 safe_browsing::dmg::UDIFParser udif(&file_stream);
120 bool expected_parse_success =
121 UDIFTestCase::UDIF_PARSE & test_case.expected_results;
122 ASSERT_EQ(expected_parse_success, udif.Parse());
123 if (!expected_parse_success)
124 return;
126 size_t expected_partition_count = 0;
127 for (; test_case.expected_partitions[expected_partition_count];
128 ++expected_partition_count) {
131 EXPECT_EQ(expected_partition_count, udif.GetNumberOfPartitions());
133 for (size_t i = 0; i < udif.GetNumberOfPartitions(); ++i) {
134 SCOPED_TRACE(base::StringPrintf("partition %zu", i));
135 scoped_ptr<ReadStream> stream = udif.GetPartitionReadStream(i);
137 // Apple_HFS will match both HFS and HFSX.
138 if (udif.GetPartitionType(i).find("Apple_HFS") != std::string::npos) {
139 ASSERT_EQ(
140 (UDIFTestCase::GET_HFS_STREAM & test_case.expected_results) != 0,
141 stream.get() != nullptr);
142 if (!stream)
143 continue;
145 EXPECT_EQ(1024, stream->Seek(1024, SEEK_SET));
147 HFSPlusVolumeHeader header = {0};
148 bool expect_read_success =
149 test_case.expected_results & UDIFTestCase::READ_UDIF_DATA;
150 EXPECT_EQ(expect_read_success, stream->ReadType(&header));
151 if (!expect_read_success)
152 continue;
154 size_t size = udif.GetPartitionSize(i);
155 off_t offset = stream->Seek(-1024, SEEK_END);
156 ASSERT_GE(offset, 0);
157 EXPECT_EQ(size - 1024, static_cast<size_t>(offset));
159 HFSPlusVolumeHeader alternate_header = {0};
160 EXPECT_TRUE(stream->ReadType(&alternate_header));
162 EXPECT_EQ(0, memcmp(&header, &alternate_header, sizeof(header)));
163 EXPECT_EQ(kHFSPlusSigWord, OSSwapBigToHostInt16(header.signature));
166 if (test_case.expected_results & UDIFTestCase::READ_UDIF_DATA) {
167 EXPECT_EQ(0, stream->Seek(0, SEEK_SET));
168 size_t partition_size = udif.GetPartitionSize(i);
169 std::vector<uint8_t> data(partition_size, 0);
170 EXPECT_TRUE(stream->ReadExact(&data[0], partition_size));
176 // These tests ensure that reading the entire partition stream with different
177 // buffer sizes (and thus unaligned UDIF chunks) all succeed.
179 TEST_P(UDIFParserTest, ReadAll_8) {
180 RunReadAllTest(8);
183 TEST_P(UDIFParserTest, ReadAll_512) {
184 RunReadAllTest(512);
187 TEST_P(UDIFParserTest, ReadAll_1000) {
188 RunReadAllTest(1000);
191 TEST_P(UDIFParserTest, ReadAll_4444) {
192 RunReadAllTest(4444);
195 TEST_P(UDIFParserTest, ReadAll_8181) {
196 RunReadAllTest(8181);
199 TEST_P(UDIFParserTest, ReadAll_100000) {
200 RunReadAllTest(100000);
203 const UDIFTestCase cases[] = {
204 {"dmg_UDBZ_GPTSPUD.dmg", kGPTExpectedPartitions, UDIFTestCase::ALL_PASS},
205 {"dmg_UDBZ_NONE.dmg", kNoPartitionMap, UDIFTestCase::ALL_PASS},
206 {"dmg_UDBZ_SPUD.dmg", kAPMExpectedPartitions, UDIFTestCase::ALL_PASS},
207 {"dmg_UDCO_GPTSPUD.dmg", kGPTExpectedPartitions,
208 // ADC compression not supported.
209 UDIFTestCase::UDIF_PARSE | UDIFTestCase::GET_HFS_STREAM},
210 {"dmg_UDCO_NONE.dmg", kNoPartitionMap,
211 // ADC compression not supported.
212 UDIFTestCase::UDIF_PARSE | UDIFTestCase::GET_HFS_STREAM},
213 {"dmg_UDCO_SPUD.dmg", kAPMExpectedPartitions,
214 // ADC compression not supported.
215 UDIFTestCase::UDIF_PARSE | UDIFTestCase::GET_HFS_STREAM},
216 {"dmg_UDRO_GPTSPUD.dmg", kGPTExpectedPartitions, UDIFTestCase::ALL_PASS},
217 {"dmg_UDRO_NONE.dmg", kNoPartitionMap, UDIFTestCase::ALL_PASS},
218 {"dmg_UDRO_SPUD.dmg", kAPMExpectedPartitions, UDIFTestCase::ALL_PASS},
219 {"dmg_UDRW_GPTSPUD.dmg", kGPTExpectedPartitions,
220 // UDRW not supported.
221 UDIFTestCase::ALL_FAIL},
222 {"dmg_UDRW_NONE.dmg", kNoPartitionMap,
223 // UDRW not supported.
224 UDIFTestCase::ALL_FAIL},
225 {"dmg_UDRW_SPUD.dmg", kAPMExpectedPartitions,
226 // UDRW not supported.
227 UDIFTestCase::ALL_FAIL},
228 {"dmg_UDSP_GPTSPUD.sparseimage", kGPTExpectedPartitions,
229 // Sparse images not supported.
230 UDIFTestCase::ALL_FAIL},
231 {"dmg_UDSP_NONE.sparseimage", kNoPartitionMap,
232 // UDRW not supported.
233 UDIFTestCase::ALL_FAIL},
234 {"dmg_UDSP_SPUD.sparseimage", kAPMExpectedPartitions,
235 // Sparse images not supported.
236 UDIFTestCase::ALL_FAIL},
237 {"dmg_UDTO_GPTSPUD.cdr", kGPTExpectedPartitions,
238 // CD/DVD format not supported.
239 UDIFTestCase::ALL_FAIL},
240 {"dmg_UDTO_NONE.cdr", kNoPartitionMap,
241 // CD/DVD format not supported.
242 UDIFTestCase::ALL_FAIL},
243 {"dmg_UDTO_SPUD.cdr", kAPMExpectedPartitions,
244 // CD/DVD format not supported.
245 UDIFTestCase::ALL_FAIL},
246 {"dmg_UDZO_GPTSPUD.dmg", kGPTExpectedPartitions, UDIFTestCase::ALL_PASS},
247 {"dmg_UDZO_SPUD.dmg", kAPMExpectedPartitions, UDIFTestCase::ALL_PASS},
248 {"dmg_UFBI_GPTSPUD.dmg", kGPTExpectedPartitions, UDIFTestCase::ALL_PASS},
249 {"dmg_UFBI_SPUD.dmg", kAPMExpectedPartitions, UDIFTestCase::ALL_PASS},
252 INSTANTIATE_TEST_CASE_P(UDIFParserTest, UDIFParserTest,
253 testing::ValuesIn(cases),
254 UDIFTestCase::GetTestName);
256 } // namespace
257 } // namespace dmg
258 } // namespace safe_browsing