1//===-- sanitizer_leb128.cpp ------------------------------------*- C++ -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8#include "sanitizer_common/sanitizer_leb128.h" 9 10#include <type_traits> 11 12#include "gtest/gtest.h" 13#include "sanitizer_common/sanitizer_common.h" 14#include "sanitizer_internal_defs.h" 15 16namespace __sanitizer { 17 18template <typename T> 19class Leb128Test : public ::testing::Test {}; 20 21using Leb128TestTypes = ::testing::Types<u8, u16, u32, u64>; 22TYPED_TEST_SUITE(Leb128Test, Leb128TestTypes, ); 23 24static uptr BitsNeeded(u64 v) { 25 if (!v) 26 return 1; 27 uptr r = 0; 28 if (sizeof(uptr) != sizeof(u64)) { 29 uptr uptr_bits = 8 * sizeof(uptr); 30 while (v >> uptr_bits) { 31 r += uptr_bits; 32 v >>= uptr_bits; 33 } 34 } 35 return r + MostSignificantSetBitIndex(v) + 1; 36} 37 38TYPED_TEST(Leb128Test, SignedOverflow) { 39 using T = typename std::make_signed<TypeParam>::type; 40 u8 buffer[16] = {255}; 41 T v = -128; 42 EXPECT_EQ(buffer + 1, EncodeSLEB128(v, buffer, buffer + 1)); 43 EXPECT_EQ(buffer + 1, DecodeSLEB128(buffer, buffer + 1, &v)); 44} 45 46TYPED_TEST(Leb128Test, Signed) { 47 using T = typename std::make_signed<TypeParam>::type; 48 T v = 0; 49 for (int i = 0; i < 100; ++i) { 50 u8 buffer[16] = {}; 51 u8* p = EncodeSLEB128(v, std::begin(buffer), std::end(buffer)); 52 EXPECT_EQ(int(BitsNeeded(v < 0 ? (-v - 1) : v) + 6 + 1) / 7, p - buffer) 53 << (int)v; 54 T v2; 55 u8* p2 = DecodeSLEB128(std::begin(buffer), std::end(buffer), &v2); 56 EXPECT_EQ(v, v2); 57 EXPECT_EQ(p, p2); 58 v = -TypeParam(v) * 3u + 1u; 59 } 60} 61 62TYPED_TEST(Leb128Test, UnsignedOverflow) { 63 using T = TypeParam; 64 u8 buffer[16] = {255}; 65 T v = 255; 66 EXPECT_EQ(buffer + 1, EncodeULEB128(v, buffer, buffer + 1)); 67 EXPECT_EQ(buffer + 1, DecodeULEB128(buffer, buffer + 1, &v)); 68} 69 70TYPED_TEST(Leb128Test, Unsigned) { 71 using T = TypeParam; 72 T v = 0; 73 for (int i = 0; i < 100; ++i) { 74 u8 buffer[16] = {}; 75 u8* p = EncodeULEB128(v, std::begin(buffer), std::end(buffer)); 76 EXPECT_EQ(int(BitsNeeded(v) + 6) / 7, p - buffer); 77 T v2; 78 u8* p2 = DecodeULEB128(std::begin(buffer), std::end(buffer), &v2); 79 EXPECT_EQ(v, v2); 80 EXPECT_EQ(p, p2); 81 v = v * 3 + 1; 82 } 83} 84 85} // namespace __sanitizer 86