xref: /aosp_15_r20/external/zucchini/buffer_source_unittest.cc (revision a03ca8b91e029cd15055c20c78c2e087c84792e4)
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, &region));
113   EXPECT_EQ(bytes_.size(), source_.Remaining());
114   EXPECT_TRUE(region.empty());
115 
116   EXPECT_TRUE(source_.GetRegion(2, &region));
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(), &region));
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