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_stream_reader.h"
16 :
17 : #include "gtest/gtest.h"
18 : #include "syzygy/pdb/pdb_byte_stream.h"
19 :
20 : namespace pdb {
21 :
22 : namespace {
23 :
24 : const size_t kTestDataLen = 593;
25 :
26 : class PdbStreamReaderTest : public testing::Test {
27 : public:
28 E : void SetUp() override {
29 : // Make some test data.
30 E : data_.reserve(kTestDataLen);
31 E : for (size_t i = 0; i < kTestDataLen; ++i)
32 E : data_.push_back(static_cast<uint8_t>(i));
33 :
34 E : stream_ = new PdbByteStream();
35 E : stream_->Init(&data_.at(0), data_.size());
36 E : }
37 :
38 : std::vector<uint8_t> data_;
39 : scoped_refptr<PdbByteStream> stream_;
40 : };
41 :
42 : } // namespace
43 :
44 : using PdbStreamReaderWithPositionTest = PdbStreamReaderTest;
45 :
46 E : TEST_F(PdbStreamReaderWithPositionTest, ReadAll) {
47 E : PdbStreamReaderWithPosition reader(stream_.get());
48 E : EXPECT_FALSE(reader.AtEnd());
49 E : EXPECT_EQ(0U, reader.Position());
50 :
51 E : uint8_t buf[kTestDataLen] = {};
52 E : EXPECT_TRUE(reader.Read(kTestDataLen, buf));
53 E : EXPECT_EQ(0, ::memcmp(&data_.at(0), buf, sizeof(buf)));
54 :
55 E : EXPECT_TRUE(reader.AtEnd());
56 E : EXPECT_EQ(kTestDataLen, reader.Position());
57 E : EXPECT_FALSE(reader.Read(1, buf));
58 E : }
59 :
60 E : TEST_F(PdbStreamReaderWithPositionTest, ReadPartial) {
61 : // Create a stream over a subset of the pdb stream_.
62 E : const size_t kStartOffs = 4;
63 E : const size_t kLength = 7;
64 E : PdbStreamReaderWithPosition reader(kStartOffs, kLength, stream_.get());
65 E : EXPECT_FALSE(reader.AtEnd());
66 E : EXPECT_EQ(0U, reader.Position());
67 :
68 E : uint8_t buf[kLength] = {};
69 E : EXPECT_TRUE(reader.Read(sizeof(buf), buf));
70 E : EXPECT_EQ(0, ::memcmp(&data_.at(kStartOffs), buf, kLength));
71 :
72 E : EXPECT_TRUE(reader.AtEnd());
73 E : EXPECT_EQ(kLength, reader.Position());
74 E : EXPECT_FALSE(reader.Read(1, buf));
75 E : }
76 :
77 E : TEST_F(PdbStreamReaderWithPositionTest, SetStream) {
78 : // Test the SetStream case.
79 E : const size_t kStartOffs = 19;
80 E : const size_t kLength = 37;
81 E : PdbStreamReaderWithPosition reader;
82 E : reader.SetStream(kStartOffs, kLength, stream_.get());
83 E : EXPECT_FALSE(reader.AtEnd());
84 E : EXPECT_EQ(0U, reader.Position());
85 :
86 E : uint8_t buf[kLength] = {};
87 E : EXPECT_TRUE(reader.Read(sizeof(buf), buf));
88 E : EXPECT_EQ(0, ::memcmp(&data_.at(kStartOffs), buf, kLength));
89 :
90 E : EXPECT_TRUE(reader.AtEnd());
91 E : EXPECT_EQ(kLength, reader.Position());
92 E : EXPECT_FALSE(reader.Read(1, buf));
93 E : }
94 :
95 E : TEST_F(PdbStreamReaderWithPositionTest, EmptyTailRead) {
96 : // Create an empty stream over the tail of the stream.
97 E : PdbStreamReaderWithPosition tail_empty(stream_->length(), 0, stream_.get());
98 E : EXPECT_TRUE(tail_empty.AtEnd());
99 E : EXPECT_EQ(0U, tail_empty.Position());
100 E : uint8_t buf[1] = {};
101 E : EXPECT_FALSE(tail_empty.Read(1, buf));
102 E : }
103 :
104 E : TEST_F(PdbStreamReaderWithPositionTest, EmptyCenterRead) {
105 : // Create an empty stream over center of the stream.
106 E : PdbStreamReaderWithPosition middle_empty(stream_->length() / 2, 0,
107 : stream_.get());
108 E : EXPECT_TRUE(middle_empty.AtEnd());
109 E : EXPECT_EQ(0U, middle_empty.Position());
110 E : uint8_t buf[1] = {};
111 E : EXPECT_FALSE(middle_empty.Read(1, buf));
112 E : }
113 :
114 E : TEST_F(PdbStreamReaderWithPositionTest, Consume) {
115 E : PdbStreamReaderWithPosition reader(stream_.get());
116 :
117 E : EXPECT_EQ(0U, reader.Position());
118 E : const size_t kSeekLength = kTestDataLen / 3;
119 : // Consume forward from start.
120 E : EXPECT_TRUE(reader.Consume(kSeekLength));
121 E : EXPECT_EQ(kSeekLength, reader.Position());
122 :
123 : // Consume forward again.
124 E : EXPECT_TRUE(reader.Consume(kSeekLength));
125 E : EXPECT_EQ(2 * kSeekLength, reader.Position());
126 :
127 E : uint8_t buf[10] = {};
128 : static_assert(sizeof(buf) < kSeekLength, "buffer too large");
129 E : EXPECT_TRUE(reader.Read(sizeof(buf), buf));
130 E : EXPECT_EQ(2 * kSeekLength + sizeof(buf), reader.Position());
131 E : EXPECT_EQ(0, ::memcmp(&data_.at(2 * kSeekLength), buf, sizeof(buf)));
132 :
133 : // Consume past the end of the file, and check that the position
134 : // hasn't changed.
135 E : EXPECT_FALSE(reader.Consume(kSeekLength));
136 E : EXPECT_EQ(2 * kSeekLength + sizeof(buf), reader.Position());
137 :
138 : // Consume right to the end of the file.
139 E : EXPECT_TRUE(reader.Consume(kTestDataLen - reader.Position()));
140 E : EXPECT_EQ(kTestDataLen, reader.Position());
141 :
142 : // And validate that we can't go past the end.
143 E : EXPECT_FALSE(reader.Consume(1));
144 E : }
145 :
146 E : TEST_F(PdbStreamReaderWithPositionTest, CopyConstructor) {
147 E : const uint8_t kData[] = { 0, 1, 2, 10 };
148 E : scoped_refptr<PdbByteStream> stream(new PdbByteStream());
149 E : stream->Init(kData, sizeof(kData));
150 :
151 E : PdbStreamReaderWithPosition reader(stream.get());
152 :
153 E : uint8_t data1[sizeof(kData)] = {};
154 E : EXPECT_EQ(0U, reader.Position());
155 :
156 E : PdbStreamReaderWithPosition reader2(reader);
157 E : EXPECT_EQ(0U, reader2.Position());
158 E : EXPECT_EQ(stream.get(), reader2.stream().get());
159 :
160 E : EXPECT_TRUE(reader.Read(sizeof(data1), data1));
161 :
162 E : EXPECT_EQ(sizeof(kData), reader.Position());
163 E : EXPECT_EQ(0, reader2.Position());
164 E : EXPECT_TRUE(reader.AtEnd());
165 E : EXPECT_FALSE(reader2.AtEnd());
166 E : EXPECT_EQ(0U, ::memcmp(kData, data1, sizeof(kData)));
167 E : EXPECT_FALSE(reader.Read(1, data1));
168 :
169 E : uint8_t data2[sizeof(kData)] = {};
170 E : EXPECT_TRUE(reader2.Read(sizeof(data2), data2));
171 E : EXPECT_EQ(sizeof(kData), reader2.Position());
172 E : EXPECT_TRUE(reader2.AtEnd());
173 E : EXPECT_EQ(0U, ::memcmp(kData, data2, sizeof(kData)));
174 E : EXPECT_FALSE(reader2.Read(1, data2));
175 E : }
176 :
177 : } // namespace pdb
|