xref: /aosp_15_r20/external/zucchini/patch_utils_unittest.cc (revision a03ca8b91e029cd15055c20c78c2e087c84792e4)
1*a03ca8b9SKrzysztof Kosiński // Copyright 2017 The Chromium Authors. All rights reserved.
2*a03ca8b9SKrzysztof Kosiński // Use of this source code is governed by a BSD-style license that can be
3*a03ca8b9SKrzysztof Kosiński // found in the LICENSE file.
4*a03ca8b9SKrzysztof Kosiński 
5*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/patch_utils.h"
6*a03ca8b9SKrzysztof Kosiński 
7*a03ca8b9SKrzysztof Kosiński #include <stdint.h>
8*a03ca8b9SKrzysztof Kosiński 
9*a03ca8b9SKrzysztof Kosiński #include <iterator>
10*a03ca8b9SKrzysztof Kosiński #include <vector>
11*a03ca8b9SKrzysztof Kosiński 
12*a03ca8b9SKrzysztof Kosiński #include "testing/gtest/include/gtest/gtest.h"
13*a03ca8b9SKrzysztof Kosiński 
14*a03ca8b9SKrzysztof Kosiński namespace zucchini {
15*a03ca8b9SKrzysztof Kosiński 
16*a03ca8b9SKrzysztof Kosiński template <class T>
TestEncodeDecodeVarUInt(const std::vector<T> & data)17*a03ca8b9SKrzysztof Kosiński void TestEncodeDecodeVarUInt(const std::vector<T>& data) {
18*a03ca8b9SKrzysztof Kosiński   std::vector<uint8_t> buffer;
19*a03ca8b9SKrzysztof Kosiński 
20*a03ca8b9SKrzysztof Kosiński   std::vector<T> values;
21*a03ca8b9SKrzysztof Kosiński   for (T basis : data) {
22*a03ca8b9SKrzysztof Kosiński     // For variety, test the neighborhood values for each case in |data|. Some
23*a03ca8b9SKrzysztof Kosiński     // test cases may result in overflow when computing |value|, but we don't
24*a03ca8b9SKrzysztof Kosiński     // care about that.
25*a03ca8b9SKrzysztof Kosiński     for (int delta = -4; delta <= 4; ++delta) {
26*a03ca8b9SKrzysztof Kosiński       T value = delta + basis;
27*a03ca8b9SKrzysztof Kosiński       EncodeVarUInt<T>(value, std::back_inserter(buffer));
28*a03ca8b9SKrzysztof Kosiński       values.push_back(value);
29*a03ca8b9SKrzysztof Kosiński 
30*a03ca8b9SKrzysztof Kosiński       value = delta - basis;
31*a03ca8b9SKrzysztof Kosiński       EncodeVarUInt<T>(value, std::back_inserter(buffer));
32*a03ca8b9SKrzysztof Kosiński       values.push_back(value);
33*a03ca8b9SKrzysztof Kosiński     }
34*a03ca8b9SKrzysztof Kosiński   }
35*a03ca8b9SKrzysztof Kosiński 
36*a03ca8b9SKrzysztof Kosiński   auto it = buffer.begin();
37*a03ca8b9SKrzysztof Kosiński   for (T expected : values) {
38*a03ca8b9SKrzysztof Kosiński     T value = T(-1);
39*a03ca8b9SKrzysztof Kosiński     auto res = DecodeVarUInt(it, buffer.end(), &value);
40*a03ca8b9SKrzysztof Kosiński     EXPECT_NE(0, res);
41*a03ca8b9SKrzysztof Kosiński     EXPECT_EQ(expected, value);
42*a03ca8b9SKrzysztof Kosiński     it += res;
43*a03ca8b9SKrzysztof Kosiński   }
44*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(it, buffer.end());
45*a03ca8b9SKrzysztof Kosiński 
46*a03ca8b9SKrzysztof Kosiński   T value = T(-1);
47*a03ca8b9SKrzysztof Kosiński   auto res = DecodeVarUInt(it, buffer.end(), &value);
48*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(0, res);
49*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(T(-1), value);
50*a03ca8b9SKrzysztof Kosiński }
51*a03ca8b9SKrzysztof Kosiński 
52*a03ca8b9SKrzysztof Kosiński template <class T>
TestEncodeDecodeVarInt(const std::vector<T> & data)53*a03ca8b9SKrzysztof Kosiński void TestEncodeDecodeVarInt(const std::vector<T>& data) {
54*a03ca8b9SKrzysztof Kosiński   std::vector<uint8_t> buffer;
55*a03ca8b9SKrzysztof Kosiński 
56*a03ca8b9SKrzysztof Kosiński   std::vector<T> values;
57*a03ca8b9SKrzysztof Kosiński   for (T basis : data) {
58*a03ca8b9SKrzysztof Kosiński     // For variety, test the neighborhood values for each case in |data|. Some
59*a03ca8b9SKrzysztof Kosiński     // test cases may result in overflow when computing |value|, but we don't
60*a03ca8b9SKrzysztof Kosiński     // care about that.
61*a03ca8b9SKrzysztof Kosiński     for (int delta = -4; delta <= 4; ++delta) {
62*a03ca8b9SKrzysztof Kosiński       T value = delta + basis;
63*a03ca8b9SKrzysztof Kosiński       EncodeVarInt(value, std::back_inserter(buffer));
64*a03ca8b9SKrzysztof Kosiński       values.push_back(value);
65*a03ca8b9SKrzysztof Kosiński 
66*a03ca8b9SKrzysztof Kosiński       value = delta - basis;
67*a03ca8b9SKrzysztof Kosiński       EncodeVarInt(value, std::back_inserter(buffer));
68*a03ca8b9SKrzysztof Kosiński       values.push_back(value);
69*a03ca8b9SKrzysztof Kosiński     }
70*a03ca8b9SKrzysztof Kosiński   }
71*a03ca8b9SKrzysztof Kosiński 
72*a03ca8b9SKrzysztof Kosiński   auto it = buffer.begin();
73*a03ca8b9SKrzysztof Kosiński   for (T expected : values) {
74*a03ca8b9SKrzysztof Kosiński     T value = T(-1);
75*a03ca8b9SKrzysztof Kosiński     auto res = DecodeVarInt(it, buffer.end(), &value);
76*a03ca8b9SKrzysztof Kosiński     EXPECT_NE(0, res);
77*a03ca8b9SKrzysztof Kosiński     EXPECT_EQ(expected, value);
78*a03ca8b9SKrzysztof Kosiński     it += res;
79*a03ca8b9SKrzysztof Kosiński   }
80*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(it, buffer.end());
81*a03ca8b9SKrzysztof Kosiński 
82*a03ca8b9SKrzysztof Kosiński   T value = T(-1);
83*a03ca8b9SKrzysztof Kosiński   auto res = DecodeVarInt(it, buffer.end(), &value);
84*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(0, res);
85*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(T(-1), value);
86*a03ca8b9SKrzysztof Kosiński }
87*a03ca8b9SKrzysztof Kosiński 
TEST(PatchUtilsTest,EncodeDecodeVarUInt32)88*a03ca8b9SKrzysztof Kosiński TEST(PatchUtilsTest, EncodeDecodeVarUInt32) {
89*a03ca8b9SKrzysztof Kosiński   TestEncodeDecodeVarUInt<uint32_t>({0, 64, 128, 8192, 16384, 1 << 20, 1 << 21,
90*a03ca8b9SKrzysztof Kosiński                                      1 << 22, 1 << 27, 1 << 28, 0x7FFFFFFFU,
91*a03ca8b9SKrzysztof Kosiński                                      UINT32_MAX});
92*a03ca8b9SKrzysztof Kosiński }
93*a03ca8b9SKrzysztof Kosiński 
TEST(PatchUtilsTest,EncodeDecodeVarInt32)94*a03ca8b9SKrzysztof Kosiński TEST(PatchUtilsTest, EncodeDecodeVarInt32) {
95*a03ca8b9SKrzysztof Kosiński   TestEncodeDecodeVarInt<int32_t>({0, 64, 128, 8192, 16384, 1 << 20, 1 << 21,
96*a03ca8b9SKrzysztof Kosiński                                    1 << 22, 1 << 27, 1 << 28, -1, INT32_MIN,
97*a03ca8b9SKrzysztof Kosiński                                    INT32_MAX});
98*a03ca8b9SKrzysztof Kosiński }
99*a03ca8b9SKrzysztof Kosiński 
TEST(PatchUtilsTest,EncodeDecodeVarUInt64)100*a03ca8b9SKrzysztof Kosiński TEST(PatchUtilsTest, EncodeDecodeVarUInt64) {
101*a03ca8b9SKrzysztof Kosiński   TestEncodeDecodeVarUInt<uint64_t>({0, 64, 128, 8192, 16384, 1 << 20, 1 << 21,
102*a03ca8b9SKrzysztof Kosiński                                      1 << 22, 1ULL << 55, 1ULL << 56,
103*a03ca8b9SKrzysztof Kosiński                                      0x7FFFFFFFFFFFFFFFULL, UINT64_MAX});
104*a03ca8b9SKrzysztof Kosiński }
105*a03ca8b9SKrzysztof Kosiński 
TEST(PatchUtilsTest,EncodeDecodeVarInt64)106*a03ca8b9SKrzysztof Kosiński TEST(PatchUtilsTest, EncodeDecodeVarInt64) {
107*a03ca8b9SKrzysztof Kosiński   TestEncodeDecodeVarInt<int64_t>({0, 64, 128, 8192, 16384, 1 << 20, 1 << 21,
108*a03ca8b9SKrzysztof Kosiński                                    1 << 22, 1LL << 55, 1LL << 56, -1, INT64_MIN,
109*a03ca8b9SKrzysztof Kosiński                                    INT64_MAX});
110*a03ca8b9SKrzysztof Kosiński }
111*a03ca8b9SKrzysztof Kosiński 
TEST(PatchUtilsTest,DecodeVarUInt32Malformed)112*a03ca8b9SKrzysztof Kosiński TEST(PatchUtilsTest, DecodeVarUInt32Malformed) {
113*a03ca8b9SKrzysztof Kosiński   constexpr uint32_t kUninit = static_cast<uint32_t>(-1LL);
114*a03ca8b9SKrzysztof Kosiński 
115*a03ca8b9SKrzysztof Kosiński   // Output variable to ensure that on failure, the output variable is not
116*a03ca8b9SKrzysztof Kosiński   // written to.
117*a03ca8b9SKrzysztof Kosiński   uint32_t value = uint32_t(-1);
118*a03ca8b9SKrzysztof Kosiński 
119*a03ca8b9SKrzysztof Kosiński   auto TestDecodeVarInt = [&value](const std::vector<uint8_t>& buffer) {
120*a03ca8b9SKrzysztof Kosiński     value = kUninit;
121*a03ca8b9SKrzysztof Kosiński     return DecodeVarUInt(buffer.begin(), buffer.end(), &value);
122*a03ca8b9SKrzysztof Kosiński   };
123*a03ca8b9SKrzysztof Kosiński 
124*a03ca8b9SKrzysztof Kosiński   // Exhausted.
125*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(0, TestDecodeVarInt(std::vector<uint8_t>{}));
126*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(kUninit, value);
127*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(0, TestDecodeVarInt(std::vector<uint8_t>(4, 128)));
128*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(kUninit, value);
129*a03ca8b9SKrzysztof Kosiński 
130*a03ca8b9SKrzysztof Kosiński   // Overflow.
131*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(0, TestDecodeVarInt(std::vector<uint8_t>(6, 128)));
132*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(kUninit, value);
133*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(0, TestDecodeVarInt({128, 128, 128, 128, 128, 42}));
134*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(kUninit, value);
135*a03ca8b9SKrzysztof Kosiński 
136*a03ca8b9SKrzysztof Kosiński   // Following are pathological cases that are not handled for simplicity,
137*a03ca8b9SKrzysztof Kosiński   // hence decoding is expected to be successful.
138*a03ca8b9SKrzysztof Kosiński   EXPECT_NE(0, TestDecodeVarInt({128, 128, 128, 128, 16}));
139*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(uint32_t(0), value);
140*a03ca8b9SKrzysztof Kosiński   EXPECT_NE(0, TestDecodeVarInt({128, 128, 128, 128, 32}));
141*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(uint32_t(0), value);
142*a03ca8b9SKrzysztof Kosiński   EXPECT_NE(0, TestDecodeVarInt({128, 128, 128, 128, 64}));
143*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(uint32_t(0), value);
144*a03ca8b9SKrzysztof Kosiński }
145*a03ca8b9SKrzysztof Kosiński 
TEST(PatchUtilsTest,DecodeVarUInt64Malformed)146*a03ca8b9SKrzysztof Kosiński TEST(PatchUtilsTest, DecodeVarUInt64Malformed) {
147*a03ca8b9SKrzysztof Kosiński   constexpr uint64_t kUninit = static_cast<uint64_t>(-1);
148*a03ca8b9SKrzysztof Kosiński 
149*a03ca8b9SKrzysztof Kosiński   uint64_t value = kUninit;
150*a03ca8b9SKrzysztof Kosiński   auto TestDecodeVarInt = [&value](const std::vector<uint8_t>& buffer) {
151*a03ca8b9SKrzysztof Kosiński     value = kUninit;
152*a03ca8b9SKrzysztof Kosiński     return DecodeVarUInt(buffer.begin(), buffer.end(), &value);
153*a03ca8b9SKrzysztof Kosiński   };
154*a03ca8b9SKrzysztof Kosiński 
155*a03ca8b9SKrzysztof Kosiński   // Exhausted.
156*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(0, TestDecodeVarInt(std::vector<uint8_t>{}));
157*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(kUninit, value);
158*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(0, TestDecodeVarInt(std::vector<uint8_t>(9, 128)));
159*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(kUninit, value);
160*a03ca8b9SKrzysztof Kosiński 
161*a03ca8b9SKrzysztof Kosiński   // Overflow.
162*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(0, TestDecodeVarInt(std::vector<uint8_t>(10, 128)));
163*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(kUninit, value);
164*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(0, TestDecodeVarInt(
165*a03ca8b9SKrzysztof Kosiński                    {128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 42}));
166*a03ca8b9SKrzysztof Kosiński   EXPECT_EQ(kUninit, value);
167*a03ca8b9SKrzysztof Kosiński }
168*a03ca8b9SKrzysztof Kosiński 
169*a03ca8b9SKrzysztof Kosiński }  // namespace zucchini
170