From c227be6c12e5340f09b489c4aee155ce8dd082c9 Mon Sep 17 00:00:00 2001 From: Martijn van Beurden Date: Tue, 1 Aug 2023 11:30:27 +0200 Subject: [PATCH] Add multithreading to libFLAC++ and more fuzzers --- include/FLAC++/encoder.h | 2 ++ oss-fuzz/encoder.cc | 6 ++++++ oss-fuzz/reencoder.cc | 6 ++++++ src/libFLAC++/stream_encoder.cpp | 12 ++++++++++++ 4 files changed, 26 insertions(+) diff --git a/include/FLAC++/encoder.h b/include/FLAC++/encoder.h index 2400823d..7c726212 100644 --- a/include/FLAC++/encoder.h +++ b/include/FLAC++/encoder.h @@ -148,6 +148,7 @@ namespace FLAC { virtual bool set_metadata(::FLAC__StreamMetadata **metadata, uint32_t num_blocks); ///< See FLAC__stream_encoder_set_metadata() virtual bool set_metadata(FLAC::Metadata::Prototype **metadata, uint32_t num_blocks); ///< See FLAC__stream_encoder_set_metadata() virtual bool set_limit_min_bitrate(bool value); ///< See FLAC__stream_encoder_set_limit_min_bitrate() + virtual uint32_t set_num_threads(uint32_t value); ///< See FLAC__stream_encoder_set_num_threads() /* get_state() is not virtual since we want subclasses to be able to return their own state */ State get_state() const; ///< See FLAC__stream_encoder_get_state() @@ -171,6 +172,7 @@ namespace FLAC { virtual uint32_t get_rice_parameter_search_dist() const; ///< See FLAC__stream_encoder_get_rice_parameter_search_dist() virtual FLAC__uint64 get_total_samples_estimate() const; ///< See FLAC__stream_encoder_get_total_samples_estimate() virtual bool get_limit_min_bitrate() const; ///< See FLAC__stream_encoder_get_limit_min_bitrate() + virtual uint32_t get_num_threads() const; ///< See FLAC__stream_encoder_get_num_threads() virtual ::FLAC__StreamEncoderInitStatus init(); ///< See FLAC__stream_encoder_init_stream() virtual ::FLAC__StreamEncoderInitStatus init_ogg(); ///< See FLAC__stream_encoder_init_ogg_stream() diff --git a/oss-fuzz/encoder.cc b/oss-fuzz/encoder.cc index 23cb3972..1da911a9 100644 --- a/oss-fuzz/encoder.cc +++ b/oss-fuzz/encoder.cc @@ -142,6 +142,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { const bool res = encoder.set_sample_rate(ds.Get()); fuzzing::memory::memory_test(res); } + { + const bool res = encoder.set_num_threads(ds.Get()); + fuzzing::memory::memory_test(res); + } if ( size > 2 * 65535 * 4 ) { /* With large inputs and expensive options enabled, the fuzzer can get *really* slow. @@ -197,6 +201,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { res = res || encoder.set_limit_min_bitrate(true); res = res || encoder.set_blocksize(3021); res = res || encoder.set_sample_rate(44100); + res = res || (encoder.set_num_threads(4) == FLAC__STREAM_ENCODER_SET_NUM_THREADS_OK); fuzzing::memory::memory_test(res); if(res) abort(); @@ -224,6 +229,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { res = res != encoder.get_limit_min_bitrate(); res = res != encoder.get_blocksize(); res = res != encoder.get_sample_rate(); + res = res != encoder.get_num_threads(); fuzzing::memory::memory_test(res); } diff --git a/oss-fuzz/reencoder.cc b/oss-fuzz/reencoder.cc index 457fbd4c..0266702d 100644 --- a/oss-fuzz/reencoder.cc +++ b/oss-fuzz/reencoder.cc @@ -197,6 +197,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { const bool res = encoder.set_sample_rate(ds.Get()); fuzzing::memory::memory_test(res); } + { + const bool res = encoder.set_num_threads(ds.Get()); + fuzzing::memory::memory_test(res); + } decoder.set_metadata_respond_all(); @@ -254,6 +258,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { res = res || encoder.set_limit_min_bitrate(true); res = res || encoder.set_blocksize(3021); res = res || encoder.set_sample_rate(44100); + res = res || (encoder.set_num_threads(4) == FLAC__STREAM_ENCODER_SET_NUM_THREADS_OK); fuzzing::memory::memory_test(res); if(res) abort(); @@ -281,6 +286,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { res = res != encoder.get_limit_min_bitrate(); res = res != encoder.get_blocksize(); res = res != encoder.get_sample_rate(); + res = res != encoder.get_num_threads(); fuzzing::memory::memory_test(res); } diff --git a/src/libFLAC++/stream_encoder.cpp b/src/libFLAC++/stream_encoder.cpp index 83771294..816fa35f 100644 --- a/src/libFLAC++/stream_encoder.cpp +++ b/src/libFLAC++/stream_encoder.cpp @@ -217,6 +217,12 @@ namespace FLAC { return static_cast(::FLAC__stream_encoder_set_limit_min_bitrate(encoder_, value)); } + uint32_t Stream::set_num_threads(uint32_t value) + { + FLAC__ASSERT(is_valid()); + return ::FLAC__stream_encoder_set_num_threads(encoder_, value); + } + Stream::State Stream::get_state() const { FLAC__ASSERT(is_valid()); @@ -343,6 +349,12 @@ namespace FLAC { return static_cast(::FLAC__stream_encoder_get_limit_min_bitrate(encoder_)); } + uint32_t Stream::get_num_threads() const + { + FLAC__ASSERT(is_valid()); + return ::FLAC__stream_encoder_get_num_threads(encoder_); + } + ::FLAC__StreamEncoderInitStatus Stream::init() { FLAC__ASSERT(is_valid());