• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
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 
16 #include "utils/leb128.h"
17 
18 #include <gmock/gmock.h>
19 #include <gtest/gtest.h>
20 
21 namespace panda::leb128::test {
22 
23 template <class T>
24 struct TestData {
25     T value;
26     size_t size;
27     uint8_t data[10];
28 };
29 
30 // clang-format off
31 
32 static std::vector<TestData<uint64_t>> unsigned_test_data {
33     {0x00,                1, {0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
34     {0x7f,                1, {0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
35     {0xff,                2, {0xff, 0x01, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
36     {0x2d7f,              2, {0xff, 0x5a, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
37     {0xffff,              3, {0xff, 0xff, 0x03, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
38     {0x192d7f,            3, {0xff, 0xda, 0x64, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
39     {0x1592d7f,           4, {0xff, 0xda, 0xe4, 0x0a, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
40     {0x11592d7f,          5, {0xff, 0xda, 0xe4, 0x8a, 0x01, 0x80, 0x80, 0x80, 0x80, 0x80}},
41     {0xffffffff,          5, {0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, 0x80, 0x80, 0x80, 0x80}},
42     {0x1011592d7f,        6, {0xff, 0xda, 0xe4, 0x8a, 0x81, 0x02, 0x80, 0x80, 0x80, 0x80}},
43     {0xc1011592d7f,       7, {0xff, 0xda, 0xe4, 0x8a, 0x81, 0x82, 0x03, 0x80, 0x80, 0x80}},
44     {0x80c1011592d7f,     8, {0xff, 0xda, 0xe4, 0x8a, 0x81, 0x82, 0x83, 0x04, 0x80, 0x80}},
45     {0xffffffffffffffff, 10, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01}}
46 };
47 
48 static std::vector<TestData<uint64_t>> unsigned_partial_decoding_test_data {
49     {0xffffffffffffffff, 10, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03}},
50 };
51 
52 static std::vector<TestData<int8_t>> signed_test_data8 {
53     {0x00,                      1, {0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
54     {0x01,                      1, {0x01, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
55     {-1,                        1, {0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
56     {0x40,                      2, {0xc0, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
57     {static_cast<int8_t>(0x80), 2, {0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
58     {-0x40,                     1, {0x40, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}}
59 };
60 
61 static std::vector<TestData<int16_t>> signed_test_data16 {
62     {0x00,                         1, {0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
63     {0x0102,                       2, {0x82, 0x02, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
64     {-1,                           1, {0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
65     {-0x40,                        1, {0x40, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
66     {static_cast<int16_t>(0x8000), 3, {0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
67     {static_cast<int16_t>(0x4001), 3, {0x81, 0x80, 0x01, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}}
68 };
69 
70 static std::vector<TestData<int32_t>> signed_test_data32 {
71     {0x00,                             1, {0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
72     {0x01020304,                       4, {0x84, 0x86, 0x88, 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
73     {-1,                               1, {0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
74     {-0x40,                            1, {0x40, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
75     {static_cast<int32_t>(0x80000000), 5, {0x80, 0x80, 0x80, 0x80, 0x78, 0x80, 0x80, 0x80, 0x80, 0x80}},
76     {static_cast<int32_t>(0x40000001), 5, {0x81, 0x80, 0x80, 0x80, 0x04, 0x80, 0x80, 0x80, 0x80, 0x80}}
77 };
78 
79 static std::vector<TestData<int64_t>> signed_test_data64 {
80     {0x00,                                      1, {0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
81     {0x40,                                      2, {0xc0, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
82     {0x7f,                                      2, {0xff, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
83     {-1,                                        1, {0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
84     {static_cast<int64_t>(0x8000000000000000), 10, {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f}},
85     {0x7000000000000001,                       10, {0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xf0, 0x00}},
86     {0x100000000000000,                         9, {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01, 0x00}},
87     {-0x40,                                     1, {0x40, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
88     {-0x1122,                                   2, {0xde, 0x5d, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}}
89 };
90 
91 static std::vector<TestData<int8_t>> signed_partial_decoding_test_data8 {
92     {1, 10, {0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a}}
93 };
94 
95 static std::vector<TestData<int16_t>> signed_partial_decoding_test_data16 {
96     {-0x3eff, 10, {0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a}}
97 };
98 
99 static std::vector<TestData<int32_t>> signed_partial_decoding_test_data32 {
100     {0x5080c101, 10, {0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a}}
101 };
102 
103 static std::vector<TestData<int64_t>> signed_partial_decoding_test_data64 {
104     {0x9101c305080c101,                        10, {0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a}},
105     {static_cast<int64_t>(0x8000000000000000), 10, {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x5f}}
106 };
107 
108 // clang-format on
109 
110 template <class T>
TestDecodeUnsigned(const std::vector<TestData<uint64_t>> & data,bool is_partial=false)111 static void TestDecodeUnsigned(const std::vector<TestData<uint64_t>> &data, bool is_partial = false)
112 {
113     for (auto &t : data) {
114         std::ostringstream ss;
115         ss << "Test unsigned decoding ";
116         ss << std::hex << t.value;
117         ss << " with sizeof(T) = ";
118         ss << sizeof(T);
119 
120         constexpr size_t bitwidth = std::numeric_limits<T>::digits;
121 
122         auto [value, size, is_full] = DecodeUnsigned<T>(t.data);
123         EXPECT_EQ(is_full, MinimumBitsToStore(t.value) <= bitwidth && !is_partial) << ss.str();
124         EXPECT_EQ(size, is_full ? t.size : (bitwidth + 6) / 7) << ss.str();
125         EXPECT_EQ(value, static_cast<T>(t.value)) << ss.str();
126     }
127 }
128 
TEST(Leb128,DecodeUnsigned)129 TEST(Leb128, DecodeUnsigned)
130 {
131     TestDecodeUnsigned<uint8_t>(unsigned_test_data);
132     TestDecodeUnsigned<uint16_t>(unsigned_test_data);
133     TestDecodeUnsigned<uint32_t>(unsigned_test_data);
134     TestDecodeUnsigned<uint64_t>(unsigned_test_data);
135     TestDecodeUnsigned<uint64_t>(unsigned_partial_decoding_test_data, true);
136 }
137 
138 template <class T>
TestDecodeSigned(const std::vector<TestData<T>> & data,bool is_partial=false)139 static void TestDecodeSigned(const std::vector<TestData<T>> &data, bool is_partial = false)
140 {
141     for (auto &t : data) {
142         std::ostringstream ss;
143         ss << "Test signed decoding ";
144         ss << std::hex << static_cast<int64_t>(t.value);
145         ss << " with sizeof(T) = ";
146         ss << sizeof(T);
147 
148         constexpr size_t bitwidth = std::numeric_limits<std::make_unsigned_t<T>>::digits;
149 
150         auto [value, size, is_full] = DecodeSigned<T>(t.data);
151         EXPECT_EQ(is_full, !is_partial) << ss.str();
152         EXPECT_EQ(size, is_full ? t.size : (bitwidth + 6) / 7) << ss.str();
153         EXPECT_EQ(value, t.value) << ss.str();
154     }
155 }
156 
TEST(Leb128,DecodeSigned)157 TEST(Leb128, DecodeSigned)
158 {
159     TestDecodeSigned(signed_test_data8);
160     TestDecodeSigned(signed_test_data16);
161     TestDecodeSigned(signed_test_data32);
162     TestDecodeSigned(signed_test_data64);
163 
164     TestDecodeSigned(signed_partial_decoding_test_data8, true);
165     TestDecodeSigned(signed_partial_decoding_test_data16, true);
166     TestDecodeSigned(signed_partial_decoding_test_data32, true);
167     TestDecodeSigned(signed_partial_decoding_test_data64, true);
168 }
169 
TEST(Leb128,EncodeUnsigned)170 TEST(Leb128, EncodeUnsigned)
171 {
172     for (auto &t : unsigned_test_data) {
173         std::ostringstream ss;
174         ss << "Test unsigned encoding ";
175         ss << std::hex << t.value;
176 
177         std::vector<uint8_t> data(t.size);
178         size_t n = EncodeUnsigned(t.value, data.data());
179         EXPECT_EQ(n, t.size) << ss.str();
180         EXPECT_EQ(UnsignedEncodingSize(t.value), t.size) << ss.str();
181         EXPECT_THAT(data, ::testing::ElementsAreArray(t.data, t.size)) << ss.str();
182     }
183 }
184 
185 template <class T>
TestEncodeSigned(const std::vector<TestData<T>> & data_vec)186 void TestEncodeSigned(const std::vector<TestData<T>> &data_vec)
187 {
188     for (auto &t : data_vec) {
189         std::ostringstream ss;
190         ss << "Test signed encoding ";
191         ss << std::hex << static_cast<int64_t>(t.value);
192 
193         std::vector<uint8_t> data(t.size);
194         size_t n = EncodeSigned(t.value, data.data());
195         EXPECT_EQ(n, t.size) << ss.str();
196         EXPECT_EQ(SignedEncodingSize(t.value), t.size) << ss.str();
197         EXPECT_THAT(data, ::testing::ElementsAreArray(t.data, t.size)) << ss.str();
198     }
199 }
200 
TEST(Leb128,EncodeSigned)201 TEST(Leb128, EncodeSigned)
202 {
203     TestEncodeSigned(signed_test_data8);
204     TestEncodeSigned(signed_test_data16);
205     TestEncodeSigned(signed_test_data32);
206     TestEncodeSigned(signed_test_data64);
207 }
208 
209 }  // namespace panda::leb128::test
210