Skip to content

Commit

Permalink
pw_varint: Add fuzz tests
Browse files Browse the repository at this point in the history
Change-Id: I58e7f9cfa5c74280a1be7e99e0229950c9f7502d
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/143475
Reviewed-by: Alexei Frolov <[email protected]>
Commit-Queue: Aaron Green <[email protected]>
  • Loading branch information
nopsledder authored and CQ Bot Account committed May 12, 2023
1 parent e503bb9 commit 43b1a1e
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 37 deletions.
2 changes: 1 addition & 1 deletion pw_varint/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ pw_cc_test(
],
deps = [
":pw_varint",
"//pw_unit_test",
"//pw_fuzzer:fuzztest",
],
)

Expand Down
5 changes: 4 additions & 1 deletion pw_varint/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ pw_test_group("tests") {
}

pw_test("varint_test") {
deps = [ ":pw_varint" ]
deps = [
":pw_varint",
"$dir_pw_fuzzer:fuzztest",
]
sources = [
"varint_test.cc",
"varint_test_c.c",
Expand Down
2 changes: 2 additions & 0 deletions pw_varint/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# the License.

include($ENV{PW_ROOT}/pw_build/pigweed.cmake)
include($ENV{PW_ROOT}/pw_unit_test/test.cmake)

pw_add_library(pw_varint STATIC
HEADERS
Expand Down Expand Up @@ -47,6 +48,7 @@ pw_add_test(pw_varint.varint_test
varint_test_c.c
PRIVATE_DEPS
pw_varint
pw_fuzzer.fuzztest
GROUPS
modules
pw_varint
Expand Down
85 changes: 50 additions & 35 deletions pw_varint/varint_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@
#include <cstring>
#include <limits>

#include "fuzztest/fuzztest.h"
#include "gtest/gtest.h"

namespace pw::varint {
namespace {

using namespace fuzztest;

extern "C" {

// Functions defined in varint_test.c which call the varint API from C.
Expand Down Expand Up @@ -430,16 +433,26 @@ TEST_F(VarintWithBuffer, EncodeSizeSigned64_MultiByte_C) {
// tests. Set the increment to 1 to test every number (this is slow).
constexpr int kIncrement = 100'000'009;

TEST_F(VarintWithBuffer, EncodeDecodeSigned32) {
int32_t i = std::numeric_limits<int32_t>::min();
while (true) {
size_t encoded = Encode(i, buffer_);
template <typename T, typename U = T>
void EncodeDecode(T value) {
std::byte buffer[10];
size_t encoded = Encode(value, buffer);

U result;
size_t decoded = Decode(buffer, &result);

int64_t result;
size_t decoded = Decode(buffer_, &result);
EXPECT_EQ(encoded, decoded);
ASSERT_EQ(value, result);
}

void EncodeDecodeSigned32(int32_t value) {
EncodeDecode<int32_t, int64_t>(value);
}

EXPECT_EQ(encoded, decoded);
ASSERT_EQ(i, result);
TEST(Varint, EncodeDecodeSigned32Incremental) {
int32_t i = std::numeric_limits<int32_t>::min();
while (true) {
EncodeDecodeSigned32(i);

if (i > std::numeric_limits<int32_t>::max() - kIncrement) {
break;
Expand All @@ -449,55 +462,55 @@ TEST_F(VarintWithBuffer, EncodeDecodeSigned32) {
}
}

TEST_F(VarintWithBuffer, EncodeDecodeSigned32_C) {
int32_t i = std::numeric_limits<int32_t>::min();
while (true) {
size_t encoded = pw_varint_CallZigZagEncode(i, buffer_, sizeof(buffer_));
FUZZ_TEST(Varint, EncodeDecodeSigned32);

int64_t result;
size_t decoded =
pw_varint_CallZigZagDecode(buffer_, sizeof(buffer_), &result);
void EncodeDecodeUnsigned32(uint32_t value) {
EncodeDecode<uint32_t, uint64_t>(value);
}

EXPECT_EQ(encoded, decoded);
ASSERT_EQ(i, result);
TEST(Varint, EncodeDecodeUnsigned32Incremental) {
uint32_t i = 0;
while (true) {
EncodeDecodeUnsigned32(i);

if (i > std::numeric_limits<int32_t>::max() - kIncrement) {
if (i > std::numeric_limits<uint32_t>::max() - kIncrement) {
break;
}

i += kIncrement;
}
}

TEST_F(VarintWithBuffer, EncodeDecodeUnsigned32) {
uint32_t i = 0;
while (true) {
size_t encoded = Encode(i, buffer_);
FUZZ_TEST(Varint, EncodeDecodeUnsigned32);

uint64_t result;
size_t decoded = Decode(buffer_, &result);
void EncodeDecode_C(uint64_t value) {
std::byte buffer[10];
size_t encoded = pw_varint_CallEncode(value, buffer, sizeof(buffer));

EXPECT_EQ(encoded, decoded);
ASSERT_EQ(i, result);
uint64_t result;
size_t decoded = pw_varint_CallDecode(buffer, sizeof(buffer), &result);

if (i > std::numeric_limits<uint32_t>::max() - kIncrement) {
EXPECT_EQ(encoded, decoded);
ASSERT_EQ(value, result);
}

TEST(Varint, EncodeDecodeSigned32Incremental_C) {
int32_t i = std::numeric_limits<int32_t>::min();
while (true) {
EncodeDecode_C(i);

if (i > std::numeric_limits<int32_t>::max() - kIncrement) {
break;
}

i += kIncrement;
}
}

TEST_F(VarintWithBuffer, EncodeDecodeUnsigned32_C) {
TEST(Varint, EncodeDecodeUnsigned32Incremental_C) {
uint32_t i = 0;
while (true) {
size_t encoded = pw_varint_CallEncode(i, buffer_, sizeof(buffer_));

uint64_t result;
size_t decoded = pw_varint_CallDecode(buffer_, sizeof(buffer_), &result);

EXPECT_EQ(encoded, decoded);
ASSERT_EQ(i, result);
EncodeDecode_C(i);

if (i > std::numeric_limits<uint32_t>::max() - kIncrement) {
break;
Expand All @@ -507,6 +520,8 @@ TEST_F(VarintWithBuffer, EncodeDecodeUnsigned32_C) {
}
}

FUZZ_TEST(Varint, EncodeDecode_C);

template <size_t kStringSize>
auto MakeBuffer(const char (&data)[kStringSize]) {
constexpr size_t kSizeBytes = kStringSize - 1;
Expand Down

0 comments on commit 43b1a1e

Please sign in to comment.