1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/zucchini/buffer_source.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include <iterator>
11 #include <string>
12 #include <tuple>
13 #include <vector>
14
15 #include "components/zucchini/test_utils.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 namespace zucchini {
19
20 using vec = std::vector<uint8_t>;
21
22 class BufferSourceTest : public testing::Test {
23 protected:
24 std::vector<uint8_t> bytes_ = ParseHexString("10 32 54 76 98 BA DC FE 10 00");
25
26 BufferSource source_ = {bytes_.data(), bytes_.size()};
27 };
28
TEST_F(BufferSourceTest,Skip)29 TEST_F(BufferSourceTest, Skip) {
30 EXPECT_EQ(bytes_.size(), source_.Remaining());
31 source_.Skip(2);
32 EXPECT_EQ(bytes_.size() - 2, source_.Remaining());
33 source_.Skip(10); // Skipping past end just moves cursor to end.
34 EXPECT_EQ(size_t(0), source_.Remaining());
35 }
36
TEST_F(BufferSourceTest,CheckNextBytes)37 TEST_F(BufferSourceTest, CheckNextBytes) {
38 EXPECT_TRUE(source_.CheckNextBytes({0x10, 0x32, 0x54, 0x76}));
39 source_.Skip(4);
40 EXPECT_TRUE(source_.CheckNextBytes({0x98, 0xBA, 0xDC, 0xFE}));
41
42 // Cursor has not advanced, so check fails.
43 EXPECT_FALSE(source_.CheckNextBytes({0x10, 0x00}));
44
45 source_.Skip(4);
46 EXPECT_EQ(size_t(2), source_.Remaining());
47
48 // Goes beyond end by 2 bytes.
49 EXPECT_FALSE(source_.CheckNextBytes({0x10, 0x00, 0x00, 0x00}));
50 EXPECT_EQ(size_t(2), source_.Remaining());
51 }
52
TEST_F(BufferSourceTest,ConsumeBytes)53 TEST_F(BufferSourceTest, ConsumeBytes) {
54 EXPECT_FALSE(source_.ConsumeBytes({0x10, 0x00}));
55 EXPECT_EQ(bytes_.size(), source_.Remaining());
56 EXPECT_TRUE(source_.ConsumeBytes({0x10, 0x32, 0x54, 0x76}));
57 EXPECT_EQ(size_t(6), source_.Remaining());
58 EXPECT_TRUE(source_.ConsumeBytes({0x98, 0xBA, 0xDC, 0xFE}));
59 EXPECT_EQ(size_t(2), source_.Remaining());
60
61 // Goes beyond end by 2 bytes.
62 EXPECT_FALSE(source_.ConsumeBytes({0x10, 0x00, 0x00, 0x00}));
63 EXPECT_EQ(size_t(2), source_.Remaining());
64 }
65
TEST_F(BufferSourceTest,CheckNextValue)66 TEST_F(BufferSourceTest, CheckNextValue) {
67 EXPECT_TRUE(source_.CheckNextValue(uint32_t(0x76543210)));
68 EXPECT_FALSE(source_.CheckNextValue(uint32_t(0x0)));
69 EXPECT_TRUE(source_.CheckNextValue(uint64_t(0xFEDCBA9876543210)));
70 EXPECT_FALSE(source_.CheckNextValue(uint64_t(0x0)));
71
72 source_.Skip(8);
73 EXPECT_EQ(size_t(2), source_.Remaining());
74
75 // Goes beyond end by 2 bytes.
76 EXPECT_FALSE(source_.CheckNextValue(uint32_t(0x1000)));
77 }
78
79 // Supported by MSVC, g++, and clang++.
80 // Ensures no gaps in packing.
81 #pragma pack(push, 1)
82 struct ValueType {
83 uint32_t a;
84 uint16_t b;
85 };
86 #pragma pack(pop)
87
TEST_F(BufferSourceTest,GetValueIntegral)88 TEST_F(BufferSourceTest, GetValueIntegral) {
89 uint32_t value = 0;
90 EXPECT_TRUE(source_.GetValue(&value));
91 EXPECT_EQ(uint32_t(0x76543210), value);
92 EXPECT_EQ(size_t(6), source_.Remaining());
93
94 EXPECT_TRUE(source_.GetValue(&value));
95 EXPECT_EQ(uint32_t(0xFEDCBA98), value);
96 EXPECT_EQ(size_t(2), source_.Remaining());
97
98 EXPECT_FALSE(source_.GetValue(&value));
99 EXPECT_EQ(size_t(2), source_.Remaining());
100 }
101
TEST_F(BufferSourceTest,GetValueAggregate)102 TEST_F(BufferSourceTest, GetValueAggregate) {
103 ValueType value = {};
104 EXPECT_TRUE(source_.GetValue(&value));
105 EXPECT_EQ(uint32_t(0x76543210), value.a);
106 EXPECT_EQ(uint32_t(0xBA98), value.b);
107 EXPECT_EQ(size_t(4), source_.Remaining());
108 }
109
TEST_F(BufferSourceTest,GetRegion)110 TEST_F(BufferSourceTest, GetRegion) {
111 ConstBufferView region;
112 EXPECT_TRUE(source_.GetRegion(0, ®ion));
113 EXPECT_EQ(bytes_.size(), source_.Remaining());
114 EXPECT_TRUE(region.empty());
115
116 EXPECT_TRUE(source_.GetRegion(2, ®ion));
117 EXPECT_EQ(size_t(2), region.size());
118 EXPECT_EQ(vec({0x10, 0x32}), vec(region.begin(), region.end()));
119 EXPECT_EQ(size_t(8), source_.Remaining());
120
121 EXPECT_FALSE(source_.GetRegion(bytes_.size(), ®ion));
122 EXPECT_EQ(size_t(8), source_.Remaining());
123 // |region| is left untouched.
124 EXPECT_EQ(vec({0x10, 0x32}), vec(region.begin(), region.end()));
125 EXPECT_EQ(size_t(2), region.size());
126 }
127
TEST_F(BufferSourceTest,GetPointerIntegral)128 TEST_F(BufferSourceTest, GetPointerIntegral) {
129 const uint32_t* ptr = source_.GetPointer<uint32_t>();
130 EXPECT_NE(nullptr, ptr);
131 EXPECT_EQ(uint32_t(0x76543210), *ptr);
132 EXPECT_EQ(size_t(6), source_.Remaining());
133
134 ptr = source_.GetPointer<uint32_t>();
135 EXPECT_NE(nullptr, ptr);
136 EXPECT_EQ(uint32_t(0xFEDCBA98), *ptr);
137 EXPECT_EQ(size_t(2), source_.Remaining());
138
139 EXPECT_EQ(nullptr, source_.GetPointer<uint32_t>());
140 EXPECT_EQ(size_t(2), source_.Remaining());
141 }
142
TEST_F(BufferSourceTest,GetPointerAggregate)143 TEST_F(BufferSourceTest, GetPointerAggregate) {
144 const ValueType* ptr = source_.GetPointer<ValueType>();
145 EXPECT_NE(nullptr, ptr);
146 EXPECT_EQ(uint32_t(0x76543210), ptr->a);
147 EXPECT_EQ(uint32_t(0xBA98), ptr->b);
148 EXPECT_EQ(size_t(4), source_.Remaining());
149 }
150
TEST_F(BufferSourceTest,GetArrayIntegral)151 TEST_F(BufferSourceTest, GetArrayIntegral) {
152 EXPECT_EQ(nullptr, source_.GetArray<uint32_t>(3));
153
154 const uint32_t* ptr = source_.GetArray<uint32_t>(2);
155 EXPECT_NE(nullptr, ptr);
156 EXPECT_EQ(uint32_t(0x76543210), ptr[0]);
157 EXPECT_EQ(uint32_t(0xFEDCBA98), ptr[1]);
158 EXPECT_EQ(size_t(2), source_.Remaining());
159 }
160
TEST_F(BufferSourceTest,GetArrayAggregate)161 TEST_F(BufferSourceTest, GetArrayAggregate) {
162 const ValueType* ptr = source_.GetArray<ValueType>(2);
163 EXPECT_EQ(nullptr, ptr);
164
165 ptr = source_.GetArray<ValueType>(1);
166
167 EXPECT_NE(nullptr, ptr);
168 EXPECT_EQ(uint32_t(0x76543210), ptr[0].a);
169 EXPECT_EQ(uint32_t(0xBA98), ptr[0].b);
170 EXPECT_EQ(size_t(4), source_.Remaining());
171 }
172
TEST_F(BufferSourceTest,GetUleb128)173 TEST_F(BufferSourceTest, GetUleb128) {
174 using size_type = BufferSource::size_type;
175 // Result = {success, value, bytes_consumed}.
176 using Result = std::tuple<bool, uint32_t, size_type>;
177
178 constexpr uint32_t kUnInit = 0xCCCCCCCC; // Arbitrary value.
179 constexpr Result kBad{false, kUnInit, 0U};
180
181 auto run = [](const std::string hex_string) -> Result {
182 std::vector<uint8_t> bytes = ParseHexString(hex_string);
183 BufferSource source(ConstBufferView{bytes.data(), bytes.size()});
184 BufferSource::iterator base = source.begin();
185 // Initialize |value| to |kUnInit| to ensure no write on failure.
186 uint32_t value = kUnInit;
187 bool success = source.GetUleb128(&value);
188 return {success, value, source.begin() - base};
189 };
190
191 auto good = [](uint32_t value, size_type bytes_consumed) -> Result {
192 return Result{true, value, bytes_consumed};
193 };
194
195 EXPECT_EQ(good(0x0U, 1U), run("00"));
196 EXPECT_EQ(good(0x20U, 1U), run("20"));
197 EXPECT_EQ(good(0x42U, 1U), run("42"));
198 EXPECT_EQ(good(0x7FU, 1U), run("7F"));
199 EXPECT_EQ(kBad, run("80")); // Out of data.
200 EXPECT_EQ(good(0x0U, 2U), run("80 00")); // Redundant code.
201 EXPECT_EQ(good(0x80U, 2U), run("80 01"));
202 EXPECT_EQ(good(0x7FU, 2U), run("FF 00")); // Redundant (unsigned).
203 EXPECT_EQ(good(0x3FFFU, 2U), run("FF 7F"));
204 EXPECT_EQ(good(0x0U, 1U), run("00 80")); // Only reads byte 0.
205 EXPECT_EQ(kBad, run("80 80")); // Out of data.
206 EXPECT_EQ(kBad, run("F1 88")); // Out of data.
207 EXPECT_EQ(good(0x0U, 3U), run("80 80 00")); // Redundant code.
208 EXPECT_EQ(good(0x4000U, 3U), run("80 80 01"));
209 EXPECT_EQ(good(0x00100000U, 3U), run("80 80 40"));
210 EXPECT_EQ(good(0x001FFFFFU, 3U), run("FF FF 7F"));
211 EXPECT_EQ(good(0x0U, 1U), run("00 00 80")); // Only reads byte 0.
212 EXPECT_EQ(kBad, run("80 80 80")); // Out of data.
213 EXPECT_EQ(kBad, run("AB CD EF")); // Out of data.
214 EXPECT_EQ(good(0x0U, 4U), run("80 80 80 00")); // Redundant code.
215 EXPECT_EQ(good(0x00100000U, 4U), run("80 80 C0 00"));
216 EXPECT_EQ(good(0x00200000U, 4U), run("80 80 80 01"));
217 EXPECT_EQ(good(0x08000000U, 4U), run("80 80 80 40"));
218 EXPECT_EQ(good(0x001FC07FU, 4U), run("FF 80 FF 00"));
219 EXPECT_EQ(good(0x0U, 5U), run("80 80 80 80 00")); // Redundant code.
220 EXPECT_EQ(good(0x10000000U, 5U), run("80 80 80 80 01"));
221 EXPECT_EQ(good(0x10204081U, 5U), run("81 81 81 81 01"));
222 EXPECT_EQ(good(0x7FFFFFFFU, 5U), run("FF FF FF FF 07"));
223 EXPECT_EQ(good(0x80000000U, 5U), run("80 80 80 80 08"));
224 EXPECT_EQ(good(0xFFFFFFFFU, 5U), run("FF FF FF FF 0F"));
225 EXPECT_EQ(kBad, run("FF FF FF FF 80")); // Too long / out of data.
226 EXPECT_EQ(good(0x0FFFFFFFU, 5U), run("FF FF FF FF 10")); // "1" discarded.
227 EXPECT_EQ(good(0x00000000U, 5U), run("80 80 80 80 20")); // "2" discarded.
228 EXPECT_EQ(good(0xA54A952AU, 5U), run("AA AA AA AA 7A")); // "7" discarded.
229 EXPECT_EQ(kBad, run("FF FF FF FF FF 00")); // Too long.
230 }
231
TEST_F(BufferSourceTest,GetSleb128)232 TEST_F(BufferSourceTest, GetSleb128) {
233 using size_type = BufferSource::size_type;
234 // Result = {success, value, bytes_consumed}.
235 using Result = std::tuple<bool, int32_t, size_type>;
236
237 constexpr int32_t kUnInit = 0xCCCCCCCC; // Arbitrary value.
238 constexpr Result kBad{false, kUnInit, 0U};
239
240 auto run = [](const std::string hex_string) -> Result {
241 std::vector<uint8_t> bytes = ParseHexString(hex_string);
242 BufferSource source(ConstBufferView{bytes.data(), bytes.size()});
243 BufferSource::iterator base = source.begin();
244 // Initialize |value| to |kUnInit| to ensure no write on failure.
245 int32_t value = kUnInit;
246 bool success = source.GetSleb128(&value);
247 return {success, value, source.begin() - base};
248 };
249
250 auto good = [](int32_t value, size_type bytes_consumed) -> Result {
251 return Result{true, value, bytes_consumed};
252 };
253
254 EXPECT_EQ(good(0x0, 1U), run("00"));
255 EXPECT_EQ(good(0x20U, 1U), run("20"));
256 EXPECT_EQ(good(-0x3E, 1U), run("42"));
257 EXPECT_EQ(good(-0x1, 1U), run("7F"));
258 EXPECT_EQ(kBad, run("80")); // Out of data.
259 EXPECT_EQ(good(0x0, 2U), run("80 00")); // Redundant code.
260 EXPECT_EQ(good(0x80, 2U), run("80 01"));
261 EXPECT_EQ(good(0x7F, 2U), run("FF 00")); // Not redudnant.
262 EXPECT_EQ(good(-0x1, 2U), run("FF 7F")); // Redundant code.
263 EXPECT_EQ(good(0x0, 1U), run("00 80")); // Only reads byte 0.
264 EXPECT_EQ(kBad, run("80 80")); // Out of data.
265 EXPECT_EQ(kBad, run("F1 88")); // Out of data.
266 EXPECT_EQ(good(0x0, 3U), run("80 80 00")); // Redundant code.
267 EXPECT_EQ(good(0x4000, 3U), run("80 80 01"));
268 EXPECT_EQ(good(-0x100000, 3U), run("80 80 40"));
269 EXPECT_EQ(good(-0x1, 3U), run("FF FF 7F")); // Redundant code.
270 EXPECT_EQ(good(0x0, 1U), run("00 00 80")); // Only reads byte 0.
271 EXPECT_EQ(kBad, run("80 80 80")); // Out of data.
272 EXPECT_EQ(kBad, run("AB CD EF")); // Out of data.
273 EXPECT_EQ(good(0x0, 4U), run("80 80 80 00")); // Redundant code.
274 EXPECT_EQ(good(0x00100000, 4U), run("80 80 C0 00"));
275 EXPECT_EQ(good(0x00200000, 4U), run("80 80 80 01"));
276 EXPECT_EQ(good(-static_cast<int32_t>(0x08000000), 4U), run("80 80 80 40"));
277 EXPECT_EQ(good(0x001FC07F, 4U), run("FF 80 FF 00"));
278 EXPECT_EQ(good(0x0, 5U), run("80 80 80 80 00")); // Redundant code.
279 EXPECT_EQ(good(0x10000000, 5U), run("80 80 80 80 01"));
280 EXPECT_EQ(good(0x10204081, 5U), run("81 81 81 81 01"));
281 EXPECT_EQ(good(0x7FFFFFFF, 5U), run("FF FF FF FF 07"));
282 EXPECT_EQ(good(-static_cast<int32_t>(0x80000000), 5U), run("80 80 80 80 08"));
283 EXPECT_EQ(good(-0x1, 5U), run("FF FF FF FF 0F")); // Redundant code.
284 EXPECT_EQ(kBad, run("FF FF FF FF 80")); // Too long / out of data.
285 EXPECT_EQ(good(0x0FFFFFFF, 5U), run("FF FF FF FF 10")); // "1" discarded.
286 EXPECT_EQ(good(0x00000000, 5U), run("80 80 80 80 20")); // "2" discarded.
287 EXPECT_EQ(good(-0x5AB56AD6, 5U), run("AA AA AA AA 7A")); // "7" discarded.
288 EXPECT_EQ(kBad, run("FF FF FF FF FF 00")); // Too long.
289 }
290
TEST_F(BufferSourceTest,SkipLeb128)291 TEST_F(BufferSourceTest, SkipLeb128) {
292 using size_type = BufferSource::size_type;
293 // Result = {success, value, bytes_consumed}.
294 using Result = std::tuple<bool, size_type>;
295
296 constexpr Result kBad{false, 0U};
297
298 auto run = [](const std::string hex_string) -> Result {
299 std::vector<uint8_t> bytes = ParseHexString(hex_string);
300 BufferSource source(ConstBufferView{bytes.data(), bytes.size()});
301 BufferSource::iterator base = source.begin();
302 bool success = source.SkipLeb128();
303 return {success, source.begin() - base};
304 };
305
306 auto good = [](size_type bytes_consumed) -> Result {
307 return Result{true, bytes_consumed};
308 };
309
310 EXPECT_EQ(good(1U), run("00"));
311 EXPECT_EQ(good(1U), run("20"));
312 EXPECT_EQ(good(1U), run("42"));
313 EXPECT_EQ(good(1U), run("7F"));
314 EXPECT_EQ(kBad, run("80")); // Out of data.
315 EXPECT_EQ(good(2U), run("80 00")); // Redundant code.
316 EXPECT_EQ(good(2U), run("80 01"));
317 EXPECT_EQ(good(2U), run("FF 00")); // Redundant (unsigned).
318 EXPECT_EQ(good(2U), run("FF 7F"));
319 EXPECT_EQ(good(1U), run("00 80")); // Only reads byte 0.
320 EXPECT_EQ(kBad, run("80 80")); // Out of data.
321 EXPECT_EQ(kBad, run("F1 88")); // Out of data.
322 EXPECT_EQ(good(3U), run("80 80 00")); // Redundant code.
323 EXPECT_EQ(good(3U), run("80 80 01"));
324 EXPECT_EQ(good(3U), run("80 80 40"));
325 EXPECT_EQ(good(3U), run("FF FF 7F"));
326 EXPECT_EQ(good(1U), run("00 00 80")); // Only reads byte 0.
327 EXPECT_EQ(kBad, run("80 80 80")); // Out of data.
328 EXPECT_EQ(kBad, run("AB CD EF")); // Out of data.
329 EXPECT_EQ(good(4U), run("80 80 80 00")); // Redundant code.
330 EXPECT_EQ(good(4U), run("80 80 C0 00"));
331 EXPECT_EQ(good(4U), run("80 80 80 01"));
332 EXPECT_EQ(good(4U), run("80 80 80 40"));
333 EXPECT_EQ(good(4U), run("FF 80 FF 00"));
334 EXPECT_EQ(good(5U), run("80 80 80 80 00")); // Redundant code.
335 EXPECT_EQ(good(5U), run("80 80 80 80 01"));
336 EXPECT_EQ(good(5U), run("81 81 81 81 01"));
337 EXPECT_EQ(good(5U), run("FF FF FF FF 07"));
338 EXPECT_EQ(good(5U), run("80 80 80 80 08"));
339 EXPECT_EQ(good(5U), run("FF FF FF FF 0F"));
340 EXPECT_EQ(kBad, run("FF FF FF FF 80")); // Too long / out of data.
341 EXPECT_EQ(good(5U), run("FF FF FF FF 10")); // "1" discarded.
342 EXPECT_EQ(good(5U), run("80 80 80 80 20")); // "2" discarded.
343 EXPECT_EQ(good(5U), run("AA AA AA AA 7A")); // "7" discarded.
344 EXPECT_EQ(kBad, run("FF FF FF FF FF 00")); // Too long.
345 }
346
347 } // namespace zucchini
348