1 : // Copyright 2012 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/pdb/pdb_symbol_record.h"
16 :
17 : #include "base/bind.h"
18 : #include "base/files/file_util.h"
19 : #include "gmock/gmock.h"
20 : #include "gtest/gtest.h"
21 : #include "syzygy/common/binary_stream.h"
22 : #include "syzygy/core/unittest_util.h"
23 : #include "syzygy/pdb/pdb_byte_stream.h"
24 : #include "syzygy/pdb/unittest_util.h"
25 : #include "third_party/cci/Files/CvInfo.h"
26 :
27 : namespace cci = Microsoft_Cci_Pdb;
28 :
29 : namespace pdb {
30 :
31 : namespace {
32 :
33 : using testing::_;
34 : using testing::Return;
35 :
36 : class PdbVisitSymbolsTest : public testing::Test {
37 : public:
38 E : void SetUpByteStream() {
39 E : reader = new PdbByteStream();
40 E : writer = reader->GetWritableStream();
41 E : }
42 :
43 : scoped_refptr<PdbStream> reader;
44 : scoped_refptr<WritablePdbStream> writer;
45 : };
46 :
47 : class MockVisitorImpl {
48 : public:
49 E : MOCK_METHOD3(Callback, bool(uint16_t, uint16_t, common::BinaryStreamReader*));
50 : };
51 : typedef testing::StrictMock<MockVisitorImpl> MockVisitor;
52 :
53 : } // namespace
54 :
55 : #if 0
56 : TEST(PdbReadSymbolRecordTest, ReadValidSymRecordStream) {
57 : base::FilePath valid_sym_record_path = testing::GetSrcRelativePath(
58 : testing::kValidPdbSymbolRecordStreamPath);
59 :
60 : scoped_refptr<pdb::PdbFileStream> valid_sym_record_stream =
61 : testing::GetStreamFromFile(valid_sym_record_path);
62 : SymbolRecordVector symbol_vector;
63 : EXPECT_TRUE(ReadSymbolRecord(valid_sym_record_stream.get(),
64 : valid_sym_record_stream->length(),
65 : &symbol_vector));
66 : }
67 :
68 : TEST(PdbReadSymbolRecordTest, ReadInvalidSymRecordStream) {
69 : base::FilePath invalid_sym_record_path = testing::GetSrcRelativePath(
70 : testing::kInvalidPdbSymbolRecordStreamPath);
71 :
72 : scoped_refptr<pdb::PdbFileStream> invalid_sym_record_stream =
73 : testing::GetStreamFromFile(invalid_sym_record_path);
74 : SymbolRecordVector symbol_vector;
75 : EXPECT_FALSE(ReadSymbolRecord(invalid_sym_record_stream.get(),
76 : invalid_sym_record_stream->length(),
77 : &symbol_vector));
78 : }
79 : #endif
80 :
81 E : TEST_F(PdbVisitSymbolsTest, FailsOnInvalidTableSize) {
82 E : SetUpByteStream();
83 E : writer->Write(static_cast<uint32_t>(cci::C13)); // Symbol stream type.
84 E : writer->Write(static_cast<uint16_t>(4)); // Symbol length.
85 E : writer->Write(static_cast<uint16_t>(0x2937)); // Made up symbol type.
86 E : writer->Write(static_cast<uint16_t>(0)); // Dummy data.
87 :
88 E : MockVisitor visitor;
89 E : VisitSymbolsCallback callback = base::Bind(
90 : &MockVisitor::Callback, base::Unretained(&visitor));
91 :
92 : // Don't expect any calls to the visitor callback.
93 E : EXPECT_FALSE(
94 E : VisitSymbols(callback, 0, 2 * reader->length(), true, reader.get()));
95 E : }
96 :
97 E : TEST_F(PdbVisitSymbolsTest, FailsOnMissingStreamType) {
98 E : SetUpByteStream();
99 :
100 E : MockVisitor visitor;
101 E : VisitSymbolsCallback callback = base::Bind(
102 : &MockVisitor::Callback, base::Unretained(&visitor));
103 :
104 : // Don't expect any calls to the visitor callback.
105 E : EXPECT_FALSE(VisitSymbols(callback, 0, reader->length(), true, reader.get()));
106 E : }
107 :
108 E : TEST_F(PdbVisitSymbolsTest, FailsOnInvalidStreamType) {
109 E : SetUpByteStream();
110 E : writer->Write(static_cast<uint32_t>(cci::C11)); // Symbol stream type.
111 E : writer->Write(static_cast<uint16_t>(0)); // Symbol length.
112 :
113 E : MockVisitor visitor;
114 E : VisitSymbolsCallback callback = base::Bind(
115 : &MockVisitor::Callback, base::Unretained(&visitor));
116 :
117 : // Don't expect any calls to the visitor callback.
118 E : EXPECT_FALSE(VisitSymbols(callback, 0, reader->length(), true, reader.get()));
119 E : }
120 :
121 E : TEST_F(PdbVisitSymbolsTest, FailsOnMissingSymbolLength) {
122 E : SetUpByteStream();
123 E : writer->Write(static_cast<uint32_t>(cci::C13)); // Symbol stream type.
124 E : writer->Write(static_cast<uint8_t>(1)); // Partial symbol stream length.
125 :
126 E : MockVisitor visitor;
127 E : VisitSymbolsCallback callback = base::Bind(
128 : &MockVisitor::Callback, base::Unretained(&visitor));
129 :
130 : // Don't expect any calls to the visitor callback.
131 E : EXPECT_FALSE(VisitSymbols(callback, 0, reader->length(), true, reader.get()));
132 E : }
133 :
134 E : TEST_F(PdbVisitSymbolsTest, FailsOnShortSymbolLength) {
135 E : SetUpByteStream();
136 E : writer->Write(static_cast<uint32_t>(cci::C13)); // Symbol stream type.
137 E : writer->Write(static_cast<uint16_t>(1)); // Symbol length.
138 :
139 E : MockVisitor visitor;
140 E : VisitSymbolsCallback callback = base::Bind(
141 : &MockVisitor::Callback, base::Unretained(&visitor));
142 :
143 : // Don't expect any calls to the visitor callback.
144 E : EXPECT_FALSE(VisitSymbols(callback, 0, reader->length(), true, reader.get()));
145 E : }
146 :
147 E : TEST_F(PdbVisitSymbolsTest, FailsOnMissingSymbolType) {
148 E : SetUpByteStream();
149 E : writer->Write(static_cast<uint32_t>(cci::C13)); // Symbol stream type.
150 E : writer->Write(static_cast<uint16_t>(4)); // Symbol length.
151 :
152 E : MockVisitor visitor;
153 E : VisitSymbolsCallback callback = base::Bind(
154 : &MockVisitor::Callback, base::Unretained(&visitor));
155 :
156 : // Don't expect any calls to the visitor callback.
157 E : EXPECT_FALSE(VisitSymbols(callback, 0, reader->length(), true, reader.get()));
158 E : }
159 :
160 E : TEST_F(PdbVisitSymbolsTest, FailsOnMissingSymbolData) {
161 E : SetUpByteStream();
162 E : writer->Write(static_cast<uint32_t>(cci::C13)); // Symbol stream type.
163 E : writer->Write(static_cast<uint16_t>(4)); // Symbol length.
164 E : writer->Write(static_cast<uint16_t>(0x1337)); // Symbol type.
165 :
166 E : MockVisitor visitor;
167 E : VisitSymbolsCallback callback = base::Bind(
168 : &MockVisitor::Callback, base::Unretained(&visitor));
169 :
170 : // Don't expect any calls to the visitor callback.
171 E : EXPECT_FALSE(VisitSymbols(callback, 0, reader->length(), true, reader.get()));
172 E : }
173 :
174 E : TEST_F(PdbVisitSymbolsTest, SucceedsOnEmptySymbolStream) {
175 E : SetUpByteStream();
176 E : writer->Write(static_cast<uint32_t>(cci::C13)); // Symbol stream type.
177 E : writer->Write(static_cast<uint16_t>(0)); // Symbol length.
178 :
179 E : MockVisitor visitor;
180 E : VisitSymbolsCallback callback = base::Bind(
181 : &MockVisitor::Callback, base::Unretained(&visitor));
182 :
183 : // Don't expect any calls to the visitor callback.
184 E : EXPECT_TRUE(VisitSymbols(callback, 0, reader->length(), true, reader.get()));
185 E : }
186 :
187 E : TEST_F(PdbVisitSymbolsTest, EarlyTermination) {
188 E : SetUpByteStream();
189 E : writer->Write(static_cast<uint32_t>(cci::C13)); // Symbol stream type.
190 E : writer->Write(static_cast<uint16_t>(4)); // Symbol length.
191 E : writer->Write(static_cast<uint16_t>(0x2937)); // Made up symbol type.
192 E : writer->Write(static_cast<uint16_t>(0)); // Dummy data.
193 :
194 E : MockVisitor visitor;
195 E : VisitSymbolsCallback callback = base::Bind(
196 : &MockVisitor::Callback, base::Unretained(&visitor));
197 :
198 E : EXPECT_CALL(visitor, Callback(_, _, _)).Times(1).WillOnce(Return(false));
199 E : EXPECT_FALSE(VisitSymbols(callback, 0, reader->length(), true, reader.get()));
200 E : }
201 :
202 E : TEST_F(PdbVisitSymbolsTest, AllSymbolsVisitedNoHeader) {
203 E : base::FilePath valid_sym_record_path = testing::GetSrcRelativePath(
204 : testing::kValidPdbSymbolRecordStreamPath);
205 :
206 E : reader = testing::GetStreamFromFile(valid_sym_record_path);
207 :
208 E : MockVisitor visitor;
209 E : VisitSymbolsCallback callback = base::Bind(
210 : &MockVisitor::Callback, base::Unretained(&visitor));
211 :
212 : // There are 697 symbols in the sample symbol stream in test_data.
213 : EXPECT_CALL(visitor, Callback(_, _, _)).Times(697).
214 E : WillRepeatedly(Return(true));
215 E : EXPECT_TRUE(VisitSymbols(callback, 0, reader->length(), false, reader.get()));
216 E : }
217 :
218 : } // namespace pdb
|