patch_utils_unittest.cc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  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. #include "components/zucchini/patch_utils.h"
  5. #include <stdint.h>
  6. #include <iterator>
  7. #include <vector>
  8. #include "testing/gtest/include/gtest/gtest.h"
  9. namespace zucchini {
  10. template <class T>
  11. void TestEncodeDecodeVarUInt(const std::vector<T>& data) {
  12. std::vector<uint8_t> buffer;
  13. std::vector<T> values;
  14. for (T basis : data) {
  15. // For variety, test the neighborhood values for each case in |data|. Some
  16. // test cases may result in overflow when computing |value|, but we don't
  17. // care about that.
  18. for (int delta = -4; delta <= 4; ++delta) {
  19. T value = delta + basis;
  20. EncodeVarUInt<T>(value, std::back_inserter(buffer));
  21. values.push_back(value);
  22. value = delta - basis;
  23. EncodeVarUInt<T>(value, std::back_inserter(buffer));
  24. values.push_back(value);
  25. }
  26. }
  27. auto it = buffer.begin();
  28. for (T expected : values) {
  29. T value = T(-1);
  30. auto res = DecodeVarUInt(it, buffer.end(), &value);
  31. EXPECT_NE(0, res);
  32. EXPECT_EQ(expected, value);
  33. it += res;
  34. }
  35. EXPECT_EQ(it, buffer.end());
  36. T value = T(-1);
  37. auto res = DecodeVarUInt(it, buffer.end(), &value);
  38. EXPECT_EQ(0, res);
  39. EXPECT_EQ(T(-1), value);
  40. }
  41. template <class T>
  42. void TestEncodeDecodeVarInt(const std::vector<T>& data) {
  43. std::vector<uint8_t> buffer;
  44. std::vector<T> values;
  45. for (T basis : data) {
  46. // For variety, test the neighborhood values for each case in |data|. Some
  47. // test cases may result in overflow when computing |value|, but we don't
  48. // care about that.
  49. for (int delta = -4; delta <= 4; ++delta) {
  50. T value = delta + basis;
  51. EncodeVarInt(value, std::back_inserter(buffer));
  52. values.push_back(value);
  53. value = delta - basis;
  54. EncodeVarInt(value, std::back_inserter(buffer));
  55. values.push_back(value);
  56. }
  57. }
  58. auto it = buffer.begin();
  59. for (T expected : values) {
  60. T value = T(-1);
  61. auto res = DecodeVarInt(it, buffer.end(), &value);
  62. EXPECT_NE(0, res);
  63. EXPECT_EQ(expected, value);
  64. it += res;
  65. }
  66. EXPECT_EQ(it, buffer.end());
  67. T value = T(-1);
  68. auto res = DecodeVarInt(it, buffer.end(), &value);
  69. EXPECT_EQ(0, res);
  70. EXPECT_EQ(T(-1), value);
  71. }
  72. TEST(PatchUtilsTest, EncodeDecodeVarUInt32) {
  73. TestEncodeDecodeVarUInt<uint32_t>({0, 64, 128, 8192, 16384, 1 << 20, 1 << 21,
  74. 1 << 22, 1 << 27, 1 << 28, 0x7FFFFFFFU,
  75. UINT32_MAX});
  76. }
  77. TEST(PatchUtilsTest, EncodeDecodeVarInt32) {
  78. TestEncodeDecodeVarInt<int32_t>({0, 64, 128, 8192, 16384, 1 << 20, 1 << 21,
  79. 1 << 22, 1 << 27, 1 << 28, -1, INT32_MIN,
  80. INT32_MAX});
  81. }
  82. TEST(PatchUtilsTest, EncodeDecodeVarUInt64) {
  83. TestEncodeDecodeVarUInt<uint64_t>({0, 64, 128, 8192, 16384, 1 << 20, 1 << 21,
  84. 1 << 22, 1ULL << 55, 1ULL << 56,
  85. 0x7FFFFFFFFFFFFFFFULL, UINT64_MAX});
  86. }
  87. TEST(PatchUtilsTest, EncodeDecodeVarInt64) {
  88. TestEncodeDecodeVarInt<int64_t>({0, 64, 128, 8192, 16384, 1 << 20, 1 << 21,
  89. 1 << 22, 1LL << 55, 1LL << 56, -1, INT64_MIN,
  90. INT64_MAX});
  91. }
  92. TEST(PatchUtilsTest, DecodeVarUInt32Malformed) {
  93. constexpr uint32_t kUninit = static_cast<uint32_t>(-1LL);
  94. // Output variable to ensure that on failure, the output variable is not
  95. // written to.
  96. uint32_t value = uint32_t(-1);
  97. auto TestDecodeVarInt = [&value](const std::vector<uint8_t>& buffer) {
  98. value = kUninit;
  99. return DecodeVarUInt(buffer.begin(), buffer.end(), &value);
  100. };
  101. // Exhausted.
  102. EXPECT_EQ(0, TestDecodeVarInt(std::vector<uint8_t>{}));
  103. EXPECT_EQ(kUninit, value);
  104. EXPECT_EQ(0, TestDecodeVarInt(std::vector<uint8_t>(4, 128)));
  105. EXPECT_EQ(kUninit, value);
  106. // Overflow.
  107. EXPECT_EQ(0, TestDecodeVarInt(std::vector<uint8_t>(6, 128)));
  108. EXPECT_EQ(kUninit, value);
  109. EXPECT_EQ(0, TestDecodeVarInt({128, 128, 128, 128, 128, 42}));
  110. EXPECT_EQ(kUninit, value);
  111. // Following are pathological cases that are not handled for simplicity,
  112. // hence decoding is expected to be successful.
  113. EXPECT_NE(0, TestDecodeVarInt({128, 128, 128, 128, 16}));
  114. EXPECT_EQ(uint32_t(0), value);
  115. EXPECT_NE(0, TestDecodeVarInt({128, 128, 128, 128, 32}));
  116. EXPECT_EQ(uint32_t(0), value);
  117. EXPECT_NE(0, TestDecodeVarInt({128, 128, 128, 128, 64}));
  118. EXPECT_EQ(uint32_t(0), value);
  119. }
  120. TEST(PatchUtilsTest, DecodeVarUInt64Malformed) {
  121. constexpr uint64_t kUninit = static_cast<uint64_t>(-1);
  122. uint64_t value = kUninit;
  123. auto TestDecodeVarInt = [&value](const std::vector<uint8_t>& buffer) {
  124. value = kUninit;
  125. return DecodeVarUInt(buffer.begin(), buffer.end(), &value);
  126. };
  127. // Exhausted.
  128. EXPECT_EQ(0, TestDecodeVarInt(std::vector<uint8_t>{}));
  129. EXPECT_EQ(kUninit, value);
  130. EXPECT_EQ(0, TestDecodeVarInt(std::vector<uint8_t>(9, 128)));
  131. EXPECT_EQ(kUninit, value);
  132. // Overflow.
  133. EXPECT_EQ(0, TestDecodeVarInt(std::vector<uint8_t>(10, 128)));
  134. EXPECT_EQ(kUninit, value);
  135. EXPECT_EQ(0, TestDecodeVarInt(
  136. {128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 42}));
  137. EXPECT_EQ(kUninit, value);
  138. }
  139. } // namespace zucchini