// Copyright 2022 Google LLC // SPDX-License-Identifier: BSD-2-Clause #ifndef LIBAVIF_TESTS_OSS_FUZZ_AVIF_FUZZTEST_HELPERS_H_ #define LIBAVIF_TESTS_OSS_FUZZ_AVIF_FUZZTEST_HELPERS_H_ #include <cstdint> #include <cstdlib> #include <vector> #include "avif/avif.h" #include "aviftest_helpers.h" #include "avifutil.h" #include "fuzztest/fuzztest.h" #include "gtest/gtest.h" namespace avif { namespace testutil { //------------------------------------------------------------------------------ // C++ wrapper for scoped memory management of C API objects. // Exposed for convenient fuzztest reproducer output. ImagePtr CreateAvifImage8b(size_t width, size_t height, avifPixelFormat pixel_format, bool has_alpha, const std::vector<uint8_t>& samples); ImagePtr CreateAvifImage16b(size_t width, size_t height, int depth, avifPixelFormat pixel_format, bool has_alpha, const std::vector<uint16_t>& samples); std::vector<ImagePtr> CreateAvifAnim8b(size_t num_frames, size_t width, size_t height, avifPixelFormat pixel_format, bool has_alpha, const std::vector<uint8_t>& samples); std::vector<ImagePtr> CreateAvifAnim16b(size_t num_frames, size_t width, size_t height, int depth, avifPixelFormat pixel_format, bool has_alpha, const std::vector<uint16_t>& samples); EncoderPtr CreateAvifEncoder(avifCodecChoice codec_choice, int max_threads, int min_quantizer, int max_quantizer, int min_quantizer_alpha, int max_quantizer_alpha, int tile_rows_log2, int tile_cols_log2, int speed); DecoderPtr CreateAvifDecoder(avifCodecChoice codec_choice, int max_threads, avifDecoderSource requested_source, bool allow_progressive, bool allow_incremental, bool ignore_exif, bool ignore_xmp, uint32_t image_size_limit, uint32_t image_dimension_limit, uint32_t image_count_limit, avifStrictFlags strict_flags); #if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP) enum class GainMapDecodeMode { … }; DecoderPtr AddGainMapOptionsToDecoder(DecoderPtr decoder, GainMapDecodeMode gain_map_decode_mode); #endif //------------------------------------------------------------------------------ // Custom fuzztest generators. // See https://github.com/google/fuzztest/blob/main/doc/domains-reference.md. // Do not generate images wider or taller than this. inline constexpr size_t kMaxDimension = …; // In pixels. // Used to reduce kMaxDimension to keep the same complexity as a still image. inline constexpr size_t kMaxNumFramesSquareRoot = …; // Do not generate animations with more than this number of frames. inline constexpr size_t kMaxNumFrames = …; size_t GetNumSamples(size_t num_frames, size_t width, size_t height, avifPixelFormat pixel_format, bool has_alpha); // To avoid using fuzztest::internal, the return type of the functions below is // auto. inline auto ArbitraryPixelFormat() { … } // avifImage generator type: Width, height, pixel format and 8-bit samples. inline auto ArbitraryAvifImage8b() { … } // avifImage generator type: Width, height, depth, pixel format and 16-bit // samples. inline auto ArbitraryAvifImage16b() { … } // avifImage generator type: Number of frames, width, height, pixel format and // 8-bit samples. inline auto ArbitraryAvifAnim8b() { … } // avifImage generator type: Number of frames, width, height, depth, pixel // format and 16-bit samples. inline auto ArbitraryAvifAnim16b() { … } // Generator for an arbitrary ImagePtr. inline auto ArbitraryAvifImage() { … } // Generator for an arbitrary std::vector<ImagePtr>. inline auto ArbitraryAvifAnim() { … } // Generator for an arbitrary EncoderPtr. inline auto ArbitraryAvifEncoder() { … } // Generator for an arbitrary DecoderPtr with base options fuzzed (i.e. // without "experimental" options hidden behind compile flags). inline auto ArbitraryBaseAvifDecoder() { … } #if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP) // Generator for an arbitrary DecoderPtr with base options and gain map // options fuzzed, with the exception of 'ignoreColorAndAlpha' (because it would // break most tests' assumptions). inline auto ArbitraryAvifDecoderWithGainMapOptions() { … } // Generator for an arbitrary DecoderPtr. inline auto ArbitraryAvifDecoder() { … } #else // Generator for an arbitrary DecoderPtr. inline auto ArbitraryAvifDecoder() { return ArbitraryBaseAvifDecoder(); } #endif // AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP //------------------------------------------------------------------------------ // Environment setup // Sets the environment variable 'name' to the 'value' during the setup step. ::testing::Environment* SetEnv(const char* name, const char* value); inline ::testing::Environment* SetStackLimitTo512x1024Bytes() { … } //------------------------------------------------------------------------------ // Returns the paths contained in the 'TEST_DATA_DIRS' environment variable. // Several paths can be set in the variable, separated by ';'. // Returns nullptr if not set. // Tests that use ArbitraryImageWithSeeds() should // ASSERT_FALSE(GetSeedDataDirs().empty()) if they want to make sure that seeds // are actually used. std::vector<std::string> GetSeedDataDirs(); // Returns a list of test images contents (not paths) from the directory set in // the 'TEST_DATA_DIRS' environment variable, that are smaller than // 'max_file_size' and have one of the formats in 'image_formats' (or any format // if 'image_formats' is empty). // If TEST_DATA_DIRS is not set, returns an empty set. // Tests that use this should ASSERT_FALSE(GetSeedDataDirs().empty()) // if they want to make sure that seeds are actually used. // Terminates the program with abort() if TEST_DATA_DIRS is set but doesn't // contain any matching images. std::vector<std::string> GetTestImagesContents( size_t max_file_size, const std::vector<avifAppFileFormat>& image_formats); // Generator for an arbitrary ImagePtr that uses test image files as seeds. // Uses the 'TEST_DATA_DIRS' environment variable to load the seeds. // If TEST_DATA_DIRS is not set, no seeds are used. // Tests that use this should ASSERT_FALSE(GetSeedDataDirs().empty()) // if they want to make sure that seeds are actually used. // Terminates the program with abort() if TEST_DATA_DIRS is set but doesn't // contain any matching images. inline auto ArbitraryImageWithSeeds( const std::vector<avifAppFileFormat>& image_formats) { … } //------------------------------------------------------------------------------ } // namespace testutil } // namespace avif #endif // LIBAVIF_TESTS_OSS_FUZZ_AVIF_FUZZTEST_HELPERS_H_