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 21namespace panda::leb128::test { 22 23template <class T> 24struct TestData { 25 T value; 26 size_t size; 27 uint8_t data[10]; 28}; 29 30// clang-format off 31 32static 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 48static 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 52static 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 61static 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 70static 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 79static 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 91static 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 95static 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 99static 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 103static 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 110template <class T> 111static 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 129TEST(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 138template <class T> 139static 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 157TEST(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 170TEST(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 185template <class T> 186void 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 201TEST(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