1 : // Copyright 2014 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "syzygy/ar/ar_reader.h"
16 :
17 : #include "gmock/gmock.h"
18 : #include "gtest/gtest.h"
19 : #include "syzygy/ar/unittest_util.h"
20 : #include "syzygy/core/unittest_util.h"
21 :
22 : namespace ar {
23 :
24 : namespace {
25 :
26 : // Test fixture.
27 : class ArReaderTest : public testing::Test {
28 : public:
29 E : virtual void SetUp() override {
30 E : lib_path_ = testing::GetSrcRelativePath(testing::kArchiveFile);
31 E : }
32 :
33 E : void InverseIsCorrect(const ArReader& reader) {
34 : ArReader::FileNameMap::const_iterator file_it =
35 E : reader.files_inverse().begin();
36 E : for (; file_it != reader.files_inverse().end(); ++file_it)
37 E : EXPECT_EQ(file_it->first, reader.files()[file_it->second]);
38 E : }
39 :
40 : base::FilePath lib_path_;
41 : };
42 :
43 : } // namespace
44 :
45 E : TEST_F(ArReaderTest, InitAndBuildFileIndex) {
46 E : ArReader reader;
47 E : EXPECT_TRUE(reader.path().empty());
48 E : EXPECT_TRUE(reader.symbols().empty());
49 E : EXPECT_TRUE(reader.offsets().empty());
50 E : EXPECT_TRUE(reader.files().empty());
51 E : EXPECT_TRUE(reader.files_inverse().empty());
52 :
53 E : EXPECT_TRUE(reader.Init(lib_path_));
54 E : EXPECT_EQ(lib_path_, reader.path());
55 E : EXPECT_EQ(testing::kArchiveSymbolCount, reader.symbols().size());
56 E : EXPECT_EQ(testing::kArchiveFileCount, reader.offsets().size());
57 E : EXPECT_TRUE(reader.files().empty());
58 E : EXPECT_TRUE(reader.files_inverse().empty());
59 :
60 : // Check some of the symbols for accuracy.
61 E : SymbolIndexMap symbols;
62 E : symbols.insert(std::make_pair(std::string("_MOZ_Z_crc32"), 12));
63 E : SymbolIndexMap::const_iterator sym_it = symbols.begin();
64 E : for (; sym_it != symbols.end(); ++sym_it) {
65 : SymbolIndexMap::const_iterator sym_it2 = reader.symbols().find(
66 E : sym_it->first);
67 E : ASSERT_TRUE(sym_it2 != reader.symbols().end());
68 E : EXPECT_EQ(*sym_it, *sym_it2);
69 E : }
70 :
71 : // Build the filename map.
72 E : EXPECT_TRUE(reader.BuildFileIndex());
73 E : EXPECT_EQ(lib_path_, reader.path());
74 E : EXPECT_EQ(testing::kArchiveSymbolCount, reader.symbols().size());
75 E : EXPECT_EQ(testing::kArchiveFileCount, reader.offsets().size());
76 E : EXPECT_EQ(15u, reader.files().size());
77 E : EXPECT_EQ(15u, reader.files_inverse().size());
78 :
79 : // Double check the filename map inverts properly.
80 E : EXPECT_NO_FATAL_FAILURE(InverseIsCorrect(reader));
81 :
82 : typedef std::pair<std::string, uint64> FileInfo;
83 : typedef std::vector<FileInfo> FileInfos;
84 E : FileInfos expected, observed;
85 : expected.push_back(std::make_pair(std::string(
86 E : "..\\..\\build\\Debug\\obj\\zlib\\zutil.obj"), 6179ul));
87 : expected.push_back(std::make_pair(std::string(
88 E : "..\\..\\build\\Debug\\obj\\zlib\\uncompr.obj"), 3172ul));
89 : expected.push_back(std::make_pair(std::string(
90 E : "..\\..\\build\\Debug\\obj\\zlib\\trees.obj"), 38365ul));
91 : expected.push_back(std::make_pair(std::string(
92 E : "..\\..\\build\\Debug\\obj\\zlib\\inftrees.obj"), 7710ul));
93 : expected.push_back(std::make_pair(std::string(
94 E : "..\\..\\build\\Debug\\obj\\zlib\\inflate.obj"), 38078ul));
95 : expected.push_back(std::make_pair(std::string(
96 E : "..\\..\\build\\Debug\\obj\\zlib\\inffast.obj"), 7577ul));
97 : expected.push_back(std::make_pair(std::string(
98 E : "..\\..\\build\\Debug\\obj\\zlib\\infback.obj"), 19688ul));
99 : expected.push_back(std::make_pair(std::string(
100 E : "..\\..\\build\\Debug\\obj\\zlib\\gzwrite.obj"), 14454ul));
101 : expected.push_back(std::make_pair(std::string(
102 E : "..\\..\\build\\Debug\\obj\\zlib\\gzread.obj"), 21369ul));
103 : expected.push_back(std::make_pair(std::string(
104 E : "..\\..\\build\\Debug\\obj\\zlib\\gzlib.obj"), 17426ul));
105 : expected.push_back(std::make_pair(std::string(
106 E : "..\\..\\build\\Debug\\obj\\zlib\\gzclose.obj"), 3843ul));
107 : expected.push_back(std::make_pair(std::string(
108 E : "..\\..\\build\\Debug\\obj\\zlib\\deflate.obj"), 46559ul));
109 : expected.push_back(std::make_pair(std::string(
110 E : "..\\..\\build\\Debug\\obj\\zlib\\crc32.obj"), 21713ul));
111 : expected.push_back(std::make_pair(std::string(
112 E : "..\\..\\build\\Debug\\obj\\zlib\\compress.obj"), 4302ul));
113 : expected.push_back(std::make_pair(std::string(
114 E : "..\\..\\build\\Debug\\obj\\zlib\\adler32.obj"), 6738ul));
115 :
116 : // Ensure that all of the streams have the name and size that we expect.
117 E : ParsedArFileHeader header;
118 E : DataBuffer data, data7;
119 E : for (size_t i = 0; i < reader.offsets().size(); ++i) {
120 E : EXPECT_TRUE(reader.HasNext());
121 E : EXPECT_TRUE(reader.ExtractNext(&header, &data));
122 E : EXPECT_EQ(data.size(), header.size);
123 E : observed.push_back(std::make_pair(header.name, header.size));
124 :
125 : // Keep around the data from one of the streams.
126 E : if (i == 7)
127 E : std::swap(data, data7);
128 E : }
129 E : EXPECT_FALSE(reader.HasNext());
130 E : EXPECT_THAT(observed, testing::ContainerEq(expected));
131 :
132 : // Ensure that a random access read works as expected.
133 E : EXPECT_TRUE(reader.Extract(7, &header, &data));
134 E : EXPECT_EQ(data7, data);
135 E : EXPECT_TRUE(reader.HasNext());
136 E : }
137 :
138 E : TEST_F(ArReaderTest, NoFilenameTable) {
139 : base::FilePath lib = testing::GetSrcRelativePath(
140 E : testing::kWeakSymbolArchiveFile);
141 E : ArReader reader;
142 E : EXPECT_TRUE(reader.Init(lib));
143 E : EXPECT_TRUE(reader.BuildFileIndex());
144 E : EXPECT_EQ(testing::kWeakSymbolArchiveSymbolCount, reader.symbols().size());
145 E : EXPECT_EQ(testing::kWeakSymbolArchiveFileCount, reader.offsets().size());
146 E : EXPECT_EQ(testing::kWeakSymbolArchiveFileCount, reader.files().size());
147 E : }
148 :
149 E : TEST_F(ArReaderTest, DuplicateFileNames) {
150 : base::FilePath lib = testing::GetSrcRelativePath(
151 E : testing::kDuplicatesArchiveFile);
152 E : ArReader reader;
153 E : EXPECT_TRUE(reader.Init(lib));
154 E : EXPECT_TRUE(reader.BuildFileIndex());
155 E : EXPECT_EQ(reader.files().size(), reader.files_inverse().size());
156 E : EXPECT_NO_FATAL_FAILURE(InverseIsCorrect(reader));
157 :
158 E : std::set<std::string> unique_files;
159 E : for (size_t i = 0; i < reader.files().size(); ++i)
160 E : unique_files.insert(reader.files()[i]);
161 E : EXPECT_LT(unique_files.size(), reader.files().size());
162 E : }
163 :
164 E : TEST_F(ArReaderTest, EmptyFiles) {
165 : base::FilePath lib = testing::GetSrcRelativePath(
166 E : testing::kEmptyFilesArchiveFile);
167 E : ArReader reader;
168 E : EXPECT_TRUE(reader.Init(lib));
169 E : EXPECT_EQ(1u, reader.offsets().size());
170 E : EXPECT_TRUE(reader.BuildFileIndex());
171 E : EXPECT_EQ(1u, reader.files().size());
172 E : }
173 :
174 : } // namespace ar
|