1 : // Copyright 2015 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_stream_record.h"
16 :
17 : #include "base/strings/utf_string_conversions.h"
18 : #include "gtest/gtest.h"
19 : #include "syzygy/core/unittest_util.h"
20 : #include "syzygy/pdb/pdb_byte_stream.h"
21 : #include "syzygy/pe/cvinfo_ext.h"
22 :
23 : namespace pdb {
24 :
25 : namespace {
26 :
27 : class PdbStreamRecordTest : public testing::Test {
28 : protected:
29 E : void SetUp() override {
30 E : stream_ = new PdbByteStream;
31 E : write_stream_ = stream_->GetWritableStream();
32 E : }
33 :
34 E : void WriteWideString(const base::string16& wide_string) {
35 E : std::string narrow_string;
36 E : ASSERT_TRUE(base::WideToUTF8(wide_string.c_str(), wide_string.length(),
37 : &narrow_string));
38 E : ASSERT_TRUE(write_stream_->WriteString(narrow_string));
39 E : }
40 :
41 : template <typename T>
42 E : void WriteData(const T& value) {
43 E : ASSERT_TRUE(write_stream_->Write(value));
44 E : }
45 :
46 : scoped_refptr<PdbByteStream> stream_;
47 : scoped_refptr<WritablePdbStream> write_stream_;
48 : };
49 :
50 : } // namespace
51 :
52 E : TEST_F(PdbStreamRecordTest, ReadWideString) {
53 E : const base::string16 wide_string = L"base::string16 wide_string";
54 E : base::string16 control_string;
55 :
56 : // Fail when attempting to read empty stream.
57 E : EXPECT_FALSE(ReadWideString(stream_.get(), &control_string));
58 :
59 E : WriteWideString(wide_string);
60 E : EXPECT_TRUE(ReadWideString(stream_.get(), &control_string));
61 E : EXPECT_EQ(wide_string, control_string);
62 E : }
63 :
64 E : TEST_F(PdbStreamRecordTest, ReadLeafNumericConstantDirect) {
65 E : const uint16_t kVal16 = 42;
66 E : NumericConstant numeric;
67 :
68 : // Fail when attempting to read empty stream.
69 E : EXPECT_FALSE(ReadNumericConstant(stream_.get(), &numeric));
70 :
71 : // For values smaller than 0x8000 the numeric leaf reads just their value.
72 E : WriteData(kVal16);
73 E : ASSERT_TRUE(ReadNumericConstant(stream_.get(), &numeric));
74 E : EXPECT_EQ(NumericConstant::CONSTANT_UNSIGNED, numeric.kind());
75 E : EXPECT_EQ(kVal16, numeric.unsigned_value());
76 E : }
77 :
78 E : TEST_F(PdbStreamRecordTest, ReadLeafNumericConstantChar) {
79 E : const int8_t kVal8 = -42;
80 E : const uint16_t kLfChar = Microsoft_Cci_Pdb::LF_CHAR;
81 E : NumericConstant numeric;
82 :
83 : // Test reading signed 8-bit values.
84 E : WriteData(kLfChar);
85 E : WriteData(kVal8);
86 E : ASSERT_TRUE(ReadNumericConstant(stream_.get(), &numeric));
87 E : EXPECT_EQ(NumericConstant::CONSTANT_SIGNED, numeric.kind());
88 E : EXPECT_EQ(kVal8, numeric.signed_value());
89 E : }
90 :
91 E : TEST_F(PdbStreamRecordTest, ReadLeafNumericConstantUshort) {
92 E : const uint16_t kVal16 = 42;
93 E : const uint16_t kLfUshort = Microsoft_Cci_Pdb::LF_USHORT;
94 E : NumericConstant numeric;
95 :
96 : // Test reading 16-bit values inside LF_USHORT.
97 E : WriteData(kLfUshort);
98 E : WriteData(kVal16);
99 E : ASSERT_TRUE(ReadNumericConstant(stream_.get(), &numeric));
100 E : EXPECT_EQ(NumericConstant::CONSTANT_UNSIGNED, numeric.kind());
101 E : EXPECT_EQ(kVal16, numeric.unsigned_value());
102 E : }
103 :
104 E : TEST_F(PdbStreamRecordTest, ReadLeafNumericConstantShort) {
105 E : const int16_t kVal16 = -42;
106 E : const uint16_t kLfShort = Microsoft_Cci_Pdb::LF_SHORT;
107 E : NumericConstant numeric;
108 :
109 : // Test reading signed 16-bit values.
110 E : WriteData(kLfShort);
111 E : WriteData(kVal16);
112 E : ASSERT_TRUE(ReadNumericConstant(stream_.get(), &numeric));
113 E : EXPECT_EQ(NumericConstant::CONSTANT_SIGNED, numeric.kind());
114 E : EXPECT_EQ(kVal16, numeric.signed_value());
115 E : }
116 :
117 E : TEST_F(PdbStreamRecordTest, ReadLeafNumericConstantUlong) {
118 E : const uint32_t kVal32 = 1333666999;
119 E : const uint16_t kLfUlong = Microsoft_Cci_Pdb::LF_ULONG;
120 E : NumericConstant numeric;
121 :
122 : // Test reading 32-bit values.
123 E : WriteData(kLfUlong);
124 E : WriteData(kVal32);
125 E : ASSERT_TRUE(ReadNumericConstant(stream_.get(), &numeric));
126 E : EXPECT_EQ(NumericConstant::CONSTANT_UNSIGNED, numeric.kind());
127 E : EXPECT_EQ(kVal32, numeric.unsigned_value());
128 E : }
129 :
130 E : TEST_F(PdbStreamRecordTest, ReadLeafNumericConstantLong) {
131 E : const int32_t kVal32 = -1333666999;
132 E : const uint16_t kLfLong = Microsoft_Cci_Pdb::LF_LONG;
133 E : NumericConstant numeric;
134 :
135 : // Test reading signed 32-bit values.
136 E : WriteData(kLfLong);
137 E : WriteData(kVal32);
138 E : ASSERT_TRUE(ReadNumericConstant(stream_.get(), &numeric));
139 E : EXPECT_EQ(NumericConstant::CONSTANT_SIGNED, numeric.kind());
140 E : EXPECT_EQ(kVal32, numeric.signed_value());
141 E : }
142 :
143 E : TEST_F(PdbStreamRecordTest, ReadLeafUnsignedNumericUquad) {
144 E : const uint64_t kVal64 = 314159265358979;
145 E : const uint16 kLfUquad = Microsoft_Cci_Pdb::LF_UQUADWORD;
146 E : NumericConstant numeric;
147 :
148 : // Test reading 64-bit values.
149 E : WriteData(kLfUquad);
150 E : WriteData(kVal64);
151 E : ASSERT_TRUE(ReadNumericConstant(stream_.get(), &numeric));
152 E : EXPECT_EQ(NumericConstant::CONSTANT_UNSIGNED, numeric.kind());
153 E : EXPECT_EQ(kVal64, numeric.unsigned_value());
154 E : }
155 :
156 E : TEST_F(PdbStreamRecordTest, ReadLeafUnsignedNumericQuad) {
157 E : const int64_t kVal64 = -314159265358979;
158 E : const uint16 kLfQuad = Microsoft_Cci_Pdb::LF_QUADWORD;
159 E : NumericConstant numeric;
160 :
161 : // Test reading signed 64-bit values.
162 E : WriteData(kLfQuad);
163 E : WriteData(kVal64);
164 E : ASSERT_TRUE(ReadNumericConstant(stream_.get(), &numeric));
165 E : EXPECT_EQ(NumericConstant::CONSTANT_SIGNED, numeric.kind());
166 E : EXPECT_EQ(kVal64, numeric.signed_value());
167 E : }
168 :
169 E : TEST_F(PdbStreamRecordTest, ReadLeafUnsignedNumeric) {
170 E : const uint16_t kVal16 = 42;
171 : uint64_t constant;
172 :
173 : // Fail when attempting to read empty stream.
174 E : EXPECT_FALSE(ReadUnsignedNumeric(stream_.get(), &constant));
175 :
176 E : WriteData(kVal16);
177 E : ASSERT_TRUE(ReadUnsignedNumeric(stream_.get(), &constant));
178 E : EXPECT_EQ(kVal16, constant);
179 E : }
180 :
181 E : TEST_F(PdbStreamRecordTest, ReadBasicType) {
182 E : const uint32_t kValue = 0x12345678;
183 E : uint32_t control_value = 0;
184 :
185 : // Fail when attempting to read empty stream.
186 E : EXPECT_FALSE(ReadBasicType(stream_.get(), &control_value));
187 :
188 E : WriteData(kValue);
189 E : EXPECT_TRUE(ReadBasicType(stream_.get(), &control_value));
190 E : EXPECT_EQ(kValue, control_value);
191 E : }
192 :
193 : } // namespace pdb
|