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/common/buffer_parser.h"
16 : #include "gtest/gtest.h"
17 :
18 : namespace common {
19 :
20 : namespace {
21 :
22 : const char kDataBuffer[] = {
23 : 0, 1, 2, 3, 4, 5, 6, 7,
24 : 8, 9, 10, 11, 12, 13, 14, 15,
25 : 16, 17
26 : };
27 : size_t kDataBufferSize = sizeof(kDataBuffer);
28 :
29 : struct Align8 {
30 : uint8_t ui8;
31 : uint64_t ui64;
32 : };
33 :
34 : #pragma pack(push, 1)
35 : struct Align1 {
36 : uint8_t ui8;
37 : uint64_t ui64;
38 : };
39 : #pragma pack(pop)
40 :
41 : // These are effectively unittests for detail::GetAlignment.
42 : static_assert(detail::GetAlignment<uint8_t>::kAlignment == 1,
43 : "GetAlignment<uint8_t> is broken.");
44 : static_assert(detail::GetAlignment<uint16_t>::kAlignment == 2,
45 : "GetAlignment<uint16_t> is broken.");
46 : static_assert(detail::GetAlignment<uint32_t>::kAlignment == 4,
47 : "GetAlignment<uint32_t> is broken.");
48 : static_assert(detail::GetAlignment<uint64_t>::kAlignment == 8,
49 : "GetAlignment<uint64_t> is broken.");
50 : static_assert(detail::GetAlignment<Align8>::kAlignment == 8,
51 : "GetAlignment<Align4> is broken.");
52 : static_assert(detail::GetAlignment<Align1>::kAlignment == 1,
53 : "GetAlignment<Align1> is broken.");
54 :
55 : } // namespace
56 :
57 E : TEST(BinaryBufferParser, ConstructorAndSetData) {
58 E : BinaryBufferParser parser1(kDataBuffer, kDataBufferSize);
59 E : BinaryBufferParser parser2;
60 E : EXPECT_EQ(static_cast<void*>(nullptr), parser2.data());
61 E : EXPECT_EQ(0u, parser2.data_len());
62 :
63 E : parser2.SetData(kDataBuffer, kDataBufferSize);
64 E : EXPECT_EQ(parser1.data(), parser2.data());
65 E : EXPECT_EQ(parser1.data_len(), parser2.data_len());
66 E : }
67 :
68 E : TEST(BinaryBufferParser, ContainsSucceedsInBuffer) {
69 E : BinaryBufferParser parser(kDataBuffer, kDataBufferSize);
70 :
71 : // Verify that Contains succeeds and returns the right pointer
72 : // for ranges in the buffer.
73 E : for (size_t offset = 0; offset < kDataBufferSize; ++offset) {
74 E : for (size_t len = 0; len < kDataBufferSize - offset; ++len) {
75 E : ASSERT_TRUE(parser.Contains(offset, len));
76 E : }
77 E : }
78 E : }
79 :
80 E : TEST(BinaryBufferParser, ContainsFailsOnOutOfBuffer) {
81 E : BinaryBufferParser parser(kDataBuffer, kDataBufferSize);
82 :
83 : // Verify that Contains fails for ranges not in the buffer.
84 E : for (size_t offset = 0; offset < kDataBufferSize + 1; ++offset) {
85 E : ASSERT_FALSE(parser.Contains(offset, kDataBufferSize - offset + 1));
86 E : }
87 E : }
88 :
89 E : TEST(BinaryBufferParser, ContainsFailsOnOverflow) {
90 E : BinaryBufferParser parser(kDataBuffer, kDataBufferSize);
91 :
92 : // Verify that Contains fails for offsets that overflow the buffer.
93 E : for (size_t offset = 1; offset < kDataBufferSize; ++offset) {
94 E : ASSERT_FALSE(parser.Contains(-static_cast<int>(offset), offset));
95 E : ASSERT_FALSE(parser.Contains(offset, -static_cast<int>(offset)));
96 E : }
97 E : }
98 :
99 E : TEST(BinaryBufferParser, GetAtSucceedsInBuffer) {
100 E : BinaryBufferParser parser(kDataBuffer, kDataBufferSize);
101 :
102 : // Verify that GetAt succeeds and returns the right pointer
103 : // for ranges in the buffer.
104 E : for (size_t offset = 0; offset < kDataBufferSize; ++offset) {
105 E : for (size_t len = 0; len < kDataBufferSize - offset; ++len) {
106 E : const void* ptr = NULL;
107 :
108 E : ASSERT_TRUE(parser.GetAt(offset, len, &ptr));
109 E : ASSERT_TRUE(ptr != NULL);
110 E : if (len > 0) {
111 E : ASSERT_EQ(offset, *reinterpret_cast<const char*>(ptr));
112 : }
113 E : }
114 E : }
115 E : }
116 :
117 : namespace {
118 : struct Foo { int a; int b; };
119 : } // namespace
120 :
121 E : TEST(BinaryBufferParser, GetAtTyped) {
122 : static const char kBuffer[sizeof(Foo) + 1];
123 E : BinaryBufferParser parser(kBuffer, sizeof(kBuffer));
124 :
125 E : const Foo* foo = nullptr;
126 E : EXPECT_TRUE(parser.GetAt(0, &foo));
127 E : EXPECT_EQ(parser.data(), foo);
128 :
129 E : EXPECT_FALSE(parser.GetAt(1, &foo));
130 E : EXPECT_TRUE(parser.GetAtIgnoreAlignment(1, &foo));
131 E : EXPECT_FALSE(parser.GetAt(2, &foo));
132 E : }
133 :
134 E : TEST(BinaryBufferParser, GetCountAtTyped) {
135 : static const char kBuffer[3 * sizeof(Foo) + 1];
136 E : BinaryBufferParser parser(kBuffer, sizeof(kBuffer));
137 :
138 E : const Foo* foo = nullptr;
139 E : EXPECT_TRUE(parser.GetCountAt(0, 3, &foo));
140 E : EXPECT_EQ(parser.data(), foo);
141 :
142 E : EXPECT_FALSE(parser.GetCountAt(1, 3, &foo));
143 E : EXPECT_TRUE(parser.GetCountAtIgnoreAlignment(1, 3, &foo));
144 E : EXPECT_FALSE(parser.GetCountAt(0, 4, &foo));
145 E : }
146 :
147 : template <class CharType>
148 E : void TestGetStringAt() {
149 : static const CharType kBuf[] = {
150 : L'a', L'b', L'c', L'd', L'\0',
151 : L'e', L'f', L'g',
152 : };
153 :
154 E : BinaryBufferParser parser(kBuf, sizeof(kBuf));
155 E : const CharType* str = NULL;
156 E : size_t len = 0;
157 E : ASSERT_TRUE(parser.GetStringAt(0, &str, &len));
158 E : ASSERT_EQ(4, len);
159 :
160 E : ASSERT_TRUE(parser.GetStringAt(4 * sizeof(kBuf[0]), &str, &len));
161 E : ASSERT_EQ(0, len);
162 :
163 E : ASSERT_FALSE(parser.GetStringAt(5 * sizeof(kBuf[0]), &str, &len));
164 E : ASSERT_FALSE(parser.GetStringAt(sizeof(kBuf), &str, &len));
165 E : }
166 :
167 E : TEST(BinaryBufferParser, GetStringAtSucceeds) {
168 E : TestGetStringAt<char>();
169 E : }
170 :
171 E : TEST(BinaryBufferParser, GetStringAtWideSucceeds) {
172 E : TestGetStringAt<wchar_t>();
173 E : }
174 :
175 E : TEST(BinaryBufferReader, IsAligned) {
176 E : BinaryBufferReader reader(kDataBuffer, kDataBufferSize);
177 :
178 E : EXPECT_TRUE(reader.IsAligned(1));
179 E : EXPECT_TRUE(reader.IsAligned(2));
180 E : EXPECT_TRUE(reader.IsAligned(4));
181 E : EXPECT_TRUE(reader.IsAligned(8));
182 :
183 E : EXPECT_TRUE(reader.Consume(1));
184 :
185 E : EXPECT_TRUE(reader.IsAligned(1));
186 E : EXPECT_FALSE(reader.IsAligned(2));
187 E : EXPECT_FALSE(reader.IsAligned(4));
188 E : EXPECT_FALSE(reader.IsAligned(8));
189 :
190 E : EXPECT_TRUE(reader.Consume(3));
191 E : EXPECT_TRUE(reader.IsAligned(1));
192 E : EXPECT_TRUE(reader.IsAligned(2));
193 E : EXPECT_TRUE(reader.IsAligned(4));
194 E : EXPECT_FALSE(reader.IsAligned(8));
195 E : }
196 :
197 E : TEST(BinaryBufferReader, Align) {
198 E : BinaryBufferReader reader(kDataBuffer, kDataBufferSize);
199 :
200 E : EXPECT_TRUE(reader.Align(1));
201 E : EXPECT_TRUE(reader.Align(2));
202 E : EXPECT_TRUE(reader.Align(4));
203 E : EXPECT_TRUE(reader.Align(8));
204 :
205 E : EXPECT_EQ(0, reader.pos());
206 :
207 E : EXPECT_TRUE(reader.Consume(1));
208 E : EXPECT_TRUE(reader.Align(2));
209 E : EXPECT_EQ(2, reader.pos());
210 E : EXPECT_TRUE(reader.Align(4));
211 E : EXPECT_EQ(4, reader.pos());
212 E : }
213 :
214 E : TEST(BinaryBufferReader, PeekSucceedsInBuffer) {
215 E : BinaryBufferReader reader(kDataBuffer, kDataBufferSize);
216 :
217 : // Verify that Peek succeeds and returns the right pointer
218 : // for ranges in the buffer.
219 E : for (size_t offset = 0; offset < kDataBufferSize; ++offset) {
220 E : for (size_t len = 0; len < kDataBufferSize - offset; ++len) {
221 E : const void* ptr = NULL;
222 :
223 E : reader.set_pos(offset);
224 E : ASSERT_TRUE(reader.Peek(len, &ptr));
225 E : ASSERT_TRUE(ptr != NULL);
226 E : if (len > 0) {
227 E : ASSERT_EQ(offset, *reinterpret_cast<const char*>(ptr));
228 : }
229 E : }
230 E : }
231 E : }
232 :
233 E : TEST(BinaryBufferReader, Read) {
234 E : BinaryBufferReader reader(kDataBuffer, kDataBufferSize);
235 :
236 E : EXPECT_EQ(0, reader.pos());
237 E : const char* ptr = NULL;
238 E : EXPECT_TRUE(reader.Read(&ptr));
239 E : EXPECT_EQ(0, *ptr);
240 :
241 E : EXPECT_TRUE(reader.Read(2, &ptr));
242 E : EXPECT_EQ(1, *ptr);
243 :
244 E : EXPECT_TRUE(reader.Read(4, &ptr));
245 E : EXPECT_EQ(3, *ptr);
246 :
247 E : EXPECT_FALSE(reader.Read(kDataBufferSize, &ptr));
248 E : }
249 :
250 E : TEST(BinaryBufferReader, ReadCharString) {
251 : static const char kBuf[] = {
252 : L'a', L'b', L'c', L'd', L'\0', L'e', L'f', L'g', L'\0', L'h', L'i'
253 : };
254 E : BinaryBufferReader reader(kBuf, sizeof(kBuf));
255 :
256 E : const char* str = NULL;
257 E : size_t str_len = 0;
258 E : ASSERT_TRUE(reader.ReadString(&str, &str_len));
259 E : EXPECT_STREQ("abcd", str);
260 E : ASSERT_TRUE(reader.ReadString(&str, &str_len));
261 E : EXPECT_STREQ("efg", str);
262 E : ASSERT_FALSE(reader.ReadString(&str, &str_len));
263 E : }
264 :
265 E : TEST(BinaryBufferReader, ReadWideString) {
266 : static const wchar_t kBuf[] = {
267 : L'a', L'b', L'c', L'd', L'\0', L'e', L'f', L'g', L'\0', L'h', L'i'
268 : };
269 E : BinaryBufferReader reader(kBuf, sizeof(kBuf));
270 :
271 E : const wchar_t* str = NULL;
272 E : size_t str_len = 0;
273 E : ASSERT_TRUE(reader.ReadString(&str, &str_len));
274 E : EXPECT_STREQ(L"abcd", str);
275 E : ASSERT_TRUE(reader.ReadString(&str, &str_len));
276 E : EXPECT_STREQ(L"efg", str);
277 E : ASSERT_FALSE(reader.ReadString(&str, &str_len));
278 E : }
279 :
280 : } // namespace common
|