Add parse-only fuzz target (#3019)
This allows for higher avifDecoder::*Limit values to be tested.
diff --git a/tests/gtest/avif_fuzztest_dec.cc b/tests/gtest/avif_fuzztest_dec.cc
index be38e9e..696c0d5 100644
--- a/tests/gtest/avif_fuzztest_dec.cc
+++ b/tests/gtest/avif_fuzztest_dec.cc
@@ -4,6 +4,7 @@
#include <algorithm>
#include <cstdint>
+#include <limits>
#include "avif/avif.h"
#include "avif_fuzztest_helpers.h"
@@ -12,6 +13,7 @@
#include "gtest/gtest.h"
using ::fuzztest::Arbitrary;
+using ::fuzztest::BitFlagCombinationOf;
using ::fuzztest::ElementOf;
namespace avif {
@@ -20,13 +22,41 @@
//------------------------------------------------------------------------------
+void Parse(const std::string& arbitrary_bytes, bool is_persistent,
+ DecoderPtr decoder, avifImageContentTypeFlags content_to_decode) {
+ ASSERT_FALSE(GetSeedDataDirs().empty()); // Make sure seeds are available.
+
+ const uint8_t* data =
+ reinterpret_cast<const uint8_t*>(arbitrary_bytes.data());
+ avifIO* const io = avifIOCreateMemoryReader(data, arbitrary_bytes.size());
+ if (io == nullptr) return;
+ io->persistent = is_persistent;
+ avifDecoderSetIO(decoder.get(), io);
+ // This can lead to AVIF_RESULT_NO_CONTENT or AVIF_RESULT_NOT_IMPLEMENTED.
+ decoder->imageContentToDecode = content_to_decode;
+ // No need to worry about decoding taking too much time or memory because
+ // this test only exercizes parsing.
+ decoder->imageSizeLimit = AVIF_DEFAULT_IMAGE_SIZE_LIMIT;
+ decoder->imageDimensionLimit = std::numeric_limits<uint32_t>::max();
+ decoder->imageCountLimit = 0;
+
+ // AVIF_RESULT_INTERNAL_ERROR means a broken invariant and should not happen.
+ EXPECT_NE(avifDecoderParse(decoder.get()), AVIF_RESULT_INTERNAL_ERROR);
+}
+
+FUZZ_TEST(ParseAvifTest, Parse)
+ .WithDomains(ArbitraryImageWithSeeds({AVIF_APP_FILE_FORMAT_AVIF}),
+ /*is_persistent=*/Arbitrary<bool>(), ArbitraryAvifDecoder(),
+ BitFlagCombinationOf<avifImageContentTypeFlags>(
+ {AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA,
+ AVIF_IMAGE_CONTENT_GAIN_MAP}));
+
+//------------------------------------------------------------------------------
+
void Decode(const std::string& arbitrary_bytes, bool is_persistent,
DecoderPtr decoder, avifImageContentTypeFlags content_to_decode) {
ASSERT_FALSE(GetSeedDataDirs().empty()); // Make sure seeds are available.
- ImagePtr decoded(avifImageCreateEmpty());
- ASSERT_NE(decoded, nullptr);
-
const uint8_t* data =
reinterpret_cast<const uint8_t*>(arbitrary_bytes.data());
avifIO* const io = avifIOCreateMemoryReader(data, arbitrary_bytes.size());