diff --git a/iamf/common/read_bit_buffer.cc b/iamf/common/read_bit_buffer.cc index c812cc9..bff15b5 100644 --- a/iamf/common/read_bit_buffer.cc +++ b/iamf/common/read_bit_buffer.cc @@ -309,6 +309,9 @@ absl::Status ReadBitBuffer::ReadUnsignedLiteralInternal(const int num_bits, if (num_bits > max_num_bits) { return absl::InvalidArgumentError("num_bits must be <= max_num_bits."); } + if (num_bits < 0) { + return absl::InvalidArgumentError("num_bits must be >= 0."); + } if (buffer_bit_offset_ < 0) { return absl::InvalidArgumentError("buffer_bit_offset_ must be >= 0."); } @@ -370,6 +373,10 @@ absl::Status ReadBitBuffer::ReadUnsignedLiteralInternal(const int num_bits, std::unique_ptr MemoryBasedReadBitBuffer::CreateFromVector(int64_t capacity, const std::vector& source) { + if (capacity < 0) { + LOG(ERROR) << "MemoryBasedReadBitBuffer capacity must be >= 0."; + return nullptr; + } return absl::WrapUnique(new MemoryBasedReadBitBuffer(capacity, source)); } @@ -397,6 +404,10 @@ MemoryBasedReadBitBuffer::MemoryBasedReadBitBuffer( std::unique_ptr FileBasedReadBitBuffer::CreateFromFilePath( const int64_t capacity, const std::filesystem::path& file_path) { + if (capacity < 0) { + LOG(ERROR) << "FileBasedReadBitBuffer capacity must be >= 0."; + return nullptr; + } if (!std::filesystem::exists(file_path)) { LOG(ERROR) << "File not found: " << file_path; return nullptr; diff --git a/iamf/common/tests/BUILD b/iamf/common/tests/BUILD index 825e622..ecc21c1 100644 --- a/iamf/common/tests/BUILD +++ b/iamf/common/tests/BUILD @@ -45,6 +45,20 @@ cc_test( ], ) +cc_test( + name = "read_bit_buffer_fuzz_test", + size = "small", + srcs = ["read_bit_buffer_fuzz_test.cc"], + deps = [ + "//iamf/common:read_bit_buffer", + "//iamf/obu:types", + "@com_google_absl//absl/status", + "@com_google_absl//absl/types:span", + "@com_google_fuzztest//fuzztest", + "@com_google_googletest//:gtest_main", + ], +) + cc_library( name = "test_utils", testonly = True, diff --git a/iamf/common/tests/read_bit_buffer_fuzz_test.cc b/iamf/common/tests/read_bit_buffer_fuzz_test.cc new file mode 100644 index 0000000..1a5e8e8 --- /dev/null +++ b/iamf/common/tests/read_bit_buffer_fuzz_test.cc @@ -0,0 +1,113 @@ +#include + +#include +#include +#include + +#include "absl/status/status.h" +#include "absl/types/span.h" +#include "fuzztest/fuzztest.h" +#include "iamf/common/read_bit_buffer.h" +#include "iamf/obu/types.h" + +namespace iamf_tools { +namespace { + +void ReadUnsignedLiteral64NoUndefinedBehavior(std::vector data, + int num_bits) { + std::unique_ptr rb = + MemoryBasedReadBitBuffer::CreateFromVector(256, data); + uint64_t read_data; + absl::Status status = rb->ReadUnsignedLiteral(num_bits, read_data); +} + +FUZZ_TEST(ReadBitBufferFuzzTest, ReadUnsignedLiteral64NoUndefinedBehavior); + +void ReadUnsignedLiteral32NoUndefinedBehavior(std::vector data, + int num_bits) { + std::unique_ptr rb = + MemoryBasedReadBitBuffer::CreateFromVector(256, data); + uint32_t read_data; + absl::Status status = rb->ReadUnsignedLiteral(num_bits, read_data); +} + +FUZZ_TEST(ReadBitBufferFuzzTest, ReadUnsignedLiteral32NoUndefinedBehavior); + +void ReadUnsignedLiteral16NoUndefinedBehavior(std::vector data, + int num_bits) { + std::unique_ptr rb = + MemoryBasedReadBitBuffer::CreateFromVector(256, data); + uint16_t read_data; + absl::Status status = rb->ReadUnsignedLiteral(num_bits, read_data); +} + +FUZZ_TEST(ReadBitBufferFuzzTest, ReadUnsignedLiteral16NoUndefinedBehavior); + +void ReadUnsignedLiteral8NoUndefinedBehavior(std::vector data, + int num_bits) { + std::unique_ptr rb = + MemoryBasedReadBitBuffer::CreateFromVector(256, data); + uint8_t read_data; + absl::Status status = rb->ReadUnsignedLiteral(num_bits, read_data); +} + +FUZZ_TEST(ReadBitBufferFuzzTest, ReadUnsignedLiteral8NoUndefinedBehavior); + +void ReadSigned16NoUndefinedBehavior(std::vector data) { + std::unique_ptr rb = + MemoryBasedReadBitBuffer::CreateFromVector(256, data); + int16_t read_data; + absl::Status status = rb->ReadSigned16(read_data); +} + +FUZZ_TEST(ReadBitBufferFuzzTest, ReadSigned16NoUndefinedBehavior); + +void ReadStringNoUndefinedBehavior(std::vector data) { + std::unique_ptr rb = + MemoryBasedReadBitBuffer::CreateFromVector(256, data); + std::string read_data; + absl::Status status = rb->ReadString(read_data); +} + +FUZZ_TEST(ReadBitBufferFuzzTest, ReadStringNoUndefinedBehavior); + +void ReadULeb128NoUndefinedBehavior(std::vector data) { + std::unique_ptr rb = + MemoryBasedReadBitBuffer::CreateFromVector(256, data); + DecodedUleb128 read_data; + absl::Status status = rb->ReadULeb128(read_data); +} + +FUZZ_TEST(ReadBitBufferFuzzTest, ReadULeb128NoUndefinedBehavior); + +void ReadIso14496_1ExpandedNoUndefinedBehavior(std::vector data, + uint32_t max_class_size) { + std::unique_ptr rb = + MemoryBasedReadBitBuffer::CreateFromVector(256, data); + uint32_t read_data; + absl::Status status = rb->ReadIso14496_1Expanded(max_class_size, read_data); +} + +FUZZ_TEST(ReadBitBufferFuzzTest, ReadIso14496_1ExpandedNoUndefinedBehavior); + +void ReadUint8SpanNoUndefinedBehavior(std::vector data) { + std::unique_ptr rb = + MemoryBasedReadBitBuffer::CreateFromVector(256, data); + std::vector read_data(data.size()); + absl::Span span(read_data); + absl::Status status = rb->ReadUint8Span(span); +} + +FUZZ_TEST(ReadBitBufferFuzzTest, ReadUint8SpanNoUndefinedBehavior); + +void ReadBooleanNoUndefinedBehavior(std::vector data) { + std::unique_ptr rb = + MemoryBasedReadBitBuffer::CreateFromVector(256, data); + bool read_data; + absl::Status status = rb->ReadBoolean(read_data); +} + +FUZZ_TEST(ReadBitBufferFuzzTest, ReadBooleanNoUndefinedBehavior); + +} // namespace +} // namespace iamf_tools diff --git a/iamf/common/tests/read_bit_buffer_test.cc b/iamf/common/tests/read_bit_buffer_test.cc index 82be17c..970c58a 100644 --- a/iamf/common/tests/read_bit_buffer_test.cc +++ b/iamf/common/tests/read_bit_buffer_test.cc @@ -43,6 +43,18 @@ using ::absl_testing::StatusIs; constexpr int kBitsPerByte = 8; constexpr int kMaxUint32 = std::numeric_limits::max(); +TEST(MemoryBasedReadBitBufferTest, CreateFromVectorFailsWithNegativeCapacity) { + const std::vector source_data = {0x01, 0x23, 0x45, 0x68, 0x89}; + EXPECT_THAT(MemoryBasedReadBitBuffer::CreateFromVector(-1, source_data), + ::testing::IsNull()); +} + +TEST(FileBasedReadBitBufferTest, CreateFromFilePathFailsWithNegativeCapacity) { + const auto file_path = GetAndCleanupOutputFileName(".iamf"); + EXPECT_THAT(FileBasedReadBitBuffer::CreateFromFilePath(-1, file_path), + ::testing::IsNull()); +} + template std::unique_ptr CreateConcreteReadBitBuffer( int64_t capacity, std::vector& source_data);