1*600f14f4SXin Li /* Copyright 2019 Guido Vranken
2*600f14f4SXin Li *
3*600f14f4SXin Li * Permission is hereby granted, free of charge, to any person obtaining
4*600f14f4SXin Li * a copy of this software and associated documentation files (the
5*600f14f4SXin Li * "Software"), to deal in the Software without restriction, including
6*600f14f4SXin Li * without limitation the rights to use, copy, modify, merge, publish,
7*600f14f4SXin Li * distribute, sublicense, and/or sell copies of the Software, and to
8*600f14f4SXin Li * permit persons to whom the Software is furnished to do so, subject
9*600f14f4SXin Li * to the following conditions:
10*600f14f4SXin Li *
11*600f14f4SXin Li * The above copyright notice and this permission notice shall be
12*600f14f4SXin Li * included in all copies or substantial portions of the Software.
13*600f14f4SXin Li *
14*600f14f4SXin Li * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15*600f14f4SXin Li * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16*600f14f4SXin Li * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17*600f14f4SXin Li * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
18*600f14f4SXin Li * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19*600f14f4SXin Li * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20*600f14f4SXin Li * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21*600f14f4SXin Li * SOFTWARE.
22*600f14f4SXin Li */
23*600f14f4SXin Li
24*600f14f4SXin Li #include <cstddef>
25*600f14f4SXin Li #include <cstdint>
26*600f14f4SXin Li #include <limits>
27*600f14f4SXin Li
28*600f14f4SXin Li #include <fuzzing/datasource/datasource.hpp>
29*600f14f4SXin Li #include <fuzzing/memory.hpp>
30*600f14f4SXin Li
31*600f14f4SXin Li #include "FLAC++/encoder.h"
32*600f14f4SXin Li #include "FLAC++/decoder.h"
33*600f14f4SXin Li #include "FLAC++/metadata.h"
34*600f14f4SXin Li #include "common.h"
35*600f14f4SXin Li
36*600f14f4SXin Li #define MAX_NUM_METADATA_BLOCKS 2048
37*600f14f4SXin Li
38*600f14f4SXin Li namespace FLAC {
39*600f14f4SXin Li namespace Encoder {
40*600f14f4SXin Li class FuzzerStream : public Stream {
41*600f14f4SXin Li private:
42*600f14f4SXin Li // fuzzing::datasource::Datasource& ds;
43*600f14f4SXin Li public:
FuzzerStream(fuzzing::datasource::Datasource &)44*600f14f4SXin Li FuzzerStream(fuzzing::datasource::Datasource&) :
45*600f14f4SXin Li Stream() { }
46*600f14f4SXin Li
write_callback(const FLAC__byte buffer[],size_t bytes,uint32_t,uint32_t)47*600f14f4SXin Li ::FLAC__StreamEncoderWriteStatus write_callback(const FLAC__byte buffer[], size_t bytes, uint32_t /* samples */, uint32_t /* current_frame */) override {
48*600f14f4SXin Li fuzzing::memory::memory_test(buffer, bytes);
49*600f14f4SXin Li return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
50*600f14f4SXin Li }
51*600f14f4SXin Li };
52*600f14f4SXin Li }
53*600f14f4SXin Li namespace Decoder {
54*600f14f4SXin Li class FuzzerDecoder : public Stream {
55*600f14f4SXin Li private:
56*600f14f4SXin Li fuzzing::datasource::Datasource& ds;
57*600f14f4SXin Li FLAC::Encoder::FuzzerStream& encoder;
58*600f14f4SXin Li public:
FuzzerDecoder(fuzzing::datasource::Datasource & dsrc,FLAC::Encoder::FuzzerStream & encoder_arg)59*600f14f4SXin Li FuzzerDecoder(fuzzing::datasource::Datasource& dsrc, FLAC::Encoder::FuzzerStream& encoder_arg) :
60*600f14f4SXin Li Stream(), ds(dsrc), encoder(encoder_arg) { }
61*600f14f4SXin Li
62*600f14f4SXin Li ::FLAC__StreamMetadata * metadata_blocks[MAX_NUM_METADATA_BLOCKS] = {0};
63*600f14f4SXin Li int num_metadata_blocks = 0;
64*600f14f4SXin Li
metadata_callback(const::FLAC__StreamMetadata * metadata)65*600f14f4SXin Li void metadata_callback(const ::FLAC__StreamMetadata *metadata) override {
66*600f14f4SXin Li if(num_metadata_blocks < MAX_NUM_METADATA_BLOCKS)
67*600f14f4SXin Li if((metadata_blocks[num_metadata_blocks] = FLAC__metadata_object_clone(metadata)) != NULL)
68*600f14f4SXin Li num_metadata_blocks++;
69*600f14f4SXin Li }
70*600f14f4SXin Li
read_callback(FLAC__byte buffer[],size_t * bytes)71*600f14f4SXin Li ::FLAC__StreamDecoderReadStatus read_callback(FLAC__byte buffer[], size_t *bytes) override {
72*600f14f4SXin Li try {
73*600f14f4SXin Li const size_t maxCopySize = *bytes;
74*600f14f4SXin Li
75*600f14f4SXin Li if ( maxCopySize > 0 ) {
76*600f14f4SXin Li /* memset just to test if this overwrites anything, and triggers ASAN */
77*600f14f4SXin Li memset(buffer, 0, maxCopySize);
78*600f14f4SXin Li }
79*600f14f4SXin Li
80*600f14f4SXin Li const auto data = ds.GetData(0);
81*600f14f4SXin Li const auto dataSize = data.size();
82*600f14f4SXin Li const auto copySize = std::min(maxCopySize, dataSize);
83*600f14f4SXin Li
84*600f14f4SXin Li if ( copySize > 0 ) {
85*600f14f4SXin Li memcpy(buffer, data.data(), copySize);
86*600f14f4SXin Li }
87*600f14f4SXin Li
88*600f14f4SXin Li *bytes = copySize;
89*600f14f4SXin Li
90*600f14f4SXin Li return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
91*600f14f4SXin Li } catch ( ... ) {
92*600f14f4SXin Li return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
93*600f14f4SXin Li }
94*600f14f4SXin Li }
95*600f14f4SXin Li
write_callback(const::FLAC__Frame * frame,const FLAC__int32 * const buffer[])96*600f14f4SXin Li ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]) override {
97*600f14f4SXin Li {
98*600f14f4SXin Li fuzzing::memory::memory_test(&(frame->header), sizeof(frame->header));
99*600f14f4SXin Li fuzzing::memory::memory_test(&(frame->footer), sizeof(frame->footer));
100*600f14f4SXin Li }
101*600f14f4SXin Li
102*600f14f4SXin Li {
103*600f14f4SXin Li const auto numChannels = get_channels();
104*600f14f4SXin Li const size_t bytesPerChannel = frame->header.blocksize * sizeof(FLAC__int32);
105*600f14f4SXin Li for (size_t i = 0; i < numChannels; i++) {
106*600f14f4SXin Li fuzzing::memory::memory_test(buffer[i], bytesPerChannel);
107*600f14f4SXin Li }
108*600f14f4SXin Li }
109*600f14f4SXin Li
110*600f14f4SXin Li /* Data is checked, now pass it towards encoder */
111*600f14f4SXin Li if(encoder.get_state() == FLAC__STREAM_ENCODER_OK) {
112*600f14f4SXin Li if(encoder.get_channels() != get_channels())
113*600f14f4SXin Li return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
114*600f14f4SXin Li if(encoder.get_bits_per_sample() != get_bits_per_sample())
115*600f14f4SXin Li return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
116*600f14f4SXin Li encoder.process(buffer, frame->header.blocksize);
117*600f14f4SXin Li return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
118*600f14f4SXin Li }
119*600f14f4SXin Li else
120*600f14f4SXin Li return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
121*600f14f4SXin Li }
error_callback(::FLAC__StreamDecoderErrorStatus status)122*600f14f4SXin Li void error_callback(::FLAC__StreamDecoderErrorStatus status) override {
123*600f14f4SXin Li fuzzing::memory::memory_test(status);
124*600f14f4SXin Li }
125*600f14f4SXin Li };
126*600f14f4SXin Li }
127*600f14f4SXin Li }
128*600f14f4SXin Li
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)129*600f14f4SXin Li extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
130*600f14f4SXin Li fuzzing::datasource::Datasource ds(data, size);
131*600f14f4SXin Li FLAC::Encoder::FuzzerStream encoder(ds);
132*600f14f4SXin Li FLAC::Decoder::FuzzerDecoder decoder(ds, encoder);
133*600f14f4SXin Li
134*600f14f4SXin Li try {
135*600f14f4SXin Li const int channels = ds.Get<uint8_t>();
136*600f14f4SXin Li const int bps = ds.Get<uint8_t>();
137*600f14f4SXin Li encoder.set_channels(channels);
138*600f14f4SXin Li encoder.set_bits_per_sample(bps);
139*600f14f4SXin Li
140*600f14f4SXin Li {
141*600f14f4SXin Li const bool res = encoder.set_streamable_subset(ds.Get<bool>());
142*600f14f4SXin Li fuzzing::memory::memory_test(res);
143*600f14f4SXin Li }
144*600f14f4SXin Li {
145*600f14f4SXin Li const bool res = encoder.set_ogg_serial_number(ds.Get<long>());
146*600f14f4SXin Li fuzzing::memory::memory_test(res);
147*600f14f4SXin Li }
148*600f14f4SXin Li {
149*600f14f4SXin Li const bool res = encoder.set_verify(ds.Get<bool>());
150*600f14f4SXin Li fuzzing::memory::memory_test(res);
151*600f14f4SXin Li }
152*600f14f4SXin Li {
153*600f14f4SXin Li const bool res = encoder.set_compression_level(ds.Get<uint8_t>());
154*600f14f4SXin Li fuzzing::memory::memory_test(res);
155*600f14f4SXin Li }
156*600f14f4SXin Li {
157*600f14f4SXin Li const bool res = encoder.set_do_mid_side_stereo(ds.Get<bool>());
158*600f14f4SXin Li fuzzing::memory::memory_test(res);
159*600f14f4SXin Li }
160*600f14f4SXin Li {
161*600f14f4SXin Li const bool res = encoder.set_loose_mid_side_stereo(ds.Get<bool>());
162*600f14f4SXin Li fuzzing::memory::memory_test(res);
163*600f14f4SXin Li }
164*600f14f4SXin Li {
165*600f14f4SXin Li const bool res = encoder.set_max_lpc_order(ds.Get<uint8_t>());
166*600f14f4SXin Li fuzzing::memory::memory_test(res);
167*600f14f4SXin Li }
168*600f14f4SXin Li {
169*600f14f4SXin Li const bool res = encoder.set_qlp_coeff_precision(ds.Get<uint32_t>());
170*600f14f4SXin Li fuzzing::memory::memory_test(res);
171*600f14f4SXin Li }
172*600f14f4SXin Li {
173*600f14f4SXin Li const bool res = encoder.set_do_escape_coding(ds.Get<bool>());
174*600f14f4SXin Li fuzzing::memory::memory_test(res);
175*600f14f4SXin Li }
176*600f14f4SXin Li {
177*600f14f4SXin Li const bool res = encoder.set_min_residual_partition_order(ds.Get<uint32_t>());
178*600f14f4SXin Li fuzzing::memory::memory_test(res);
179*600f14f4SXin Li }
180*600f14f4SXin Li {
181*600f14f4SXin Li const bool res = encoder.set_max_residual_partition_order(ds.Get<uint32_t>());
182*600f14f4SXin Li fuzzing::memory::memory_test(res);
183*600f14f4SXin Li }
184*600f14f4SXin Li {
185*600f14f4SXin Li const bool res = encoder.set_total_samples_estimate(ds.Get<uint64_t>());
186*600f14f4SXin Li fuzzing::memory::memory_test(res);
187*600f14f4SXin Li }
188*600f14f4SXin Li {
189*600f14f4SXin Li const bool res = encoder.set_blocksize(ds.Get<uint16_t>());
190*600f14f4SXin Li fuzzing::memory::memory_test(res);
191*600f14f4SXin Li }
192*600f14f4SXin Li {
193*600f14f4SXin Li const bool res = encoder.set_limit_min_bitrate(ds.Get<bool>());
194*600f14f4SXin Li fuzzing::memory::memory_test(res);
195*600f14f4SXin Li }
196*600f14f4SXin Li {
197*600f14f4SXin Li const bool res = encoder.set_sample_rate(ds.Get<uint32_t>());
198*600f14f4SXin Li fuzzing::memory::memory_test(res);
199*600f14f4SXin Li }
200*600f14f4SXin Li
201*600f14f4SXin Li decoder.set_metadata_respond_all();
202*600f14f4SXin Li
203*600f14f4SXin Li {
204*600f14f4SXin Li ::FLAC__StreamDecoderInitStatus ret;
205*600f14f4SXin Li if ( ds.Get<bool>() ) {
206*600f14f4SXin Li ret = decoder.init();
207*600f14f4SXin Li } else {
208*600f14f4SXin Li ret = decoder.init_ogg();
209*600f14f4SXin Li }
210*600f14f4SXin Li
211*600f14f4SXin Li if ( ret != FLAC__STREAM_DECODER_INIT_STATUS_OK ) {
212*600f14f4SXin Li goto end;
213*600f14f4SXin Li }
214*600f14f4SXin Li
215*600f14f4SXin Li decoder.process_until_end_of_metadata();
216*600f14f4SXin Li if(decoder.num_metadata_blocks > 0)
217*600f14f4SXin Li encoder.set_metadata(decoder.metadata_blocks, decoder.num_metadata_blocks);
218*600f14f4SXin Li }
219*600f14f4SXin Li
220*600f14f4SXin Li {
221*600f14f4SXin Li ::FLAC__StreamEncoderInitStatus ret;
222*600f14f4SXin Li if ( ds.Get<bool>() ) {
223*600f14f4SXin Li ret = encoder.init();
224*600f14f4SXin Li } else {
225*600f14f4SXin Li ret = encoder.init_ogg();
226*600f14f4SXin Li }
227*600f14f4SXin Li
228*600f14f4SXin Li if ( ret != FLAC__STREAM_ENCODER_INIT_STATUS_OK ) {
229*600f14f4SXin Li goto end;
230*600f14f4SXin Li }
231*600f14f4SXin Li }
232*600f14f4SXin Li
233*600f14f4SXin Li /* These sets must fail, because encoder is already initialized */
234*600f14f4SXin Li {
235*600f14f4SXin Li bool res = false;
236*600f14f4SXin Li res = res || encoder.set_streamable_subset(true);
237*600f14f4SXin Li res = res || encoder.set_ogg_serial_number(0);
238*600f14f4SXin Li res = res || encoder.set_verify(true);
239*600f14f4SXin Li res = res || encoder.set_compression_level(0);
240*600f14f4SXin Li res = res || encoder.set_do_exhaustive_model_search(true);
241*600f14f4SXin Li res = res || encoder.set_do_mid_side_stereo(true);
242*600f14f4SXin Li res = res || encoder.set_loose_mid_side_stereo(true);
243*600f14f4SXin Li res = res || encoder.set_apodization("test");
244*600f14f4SXin Li res = res || encoder.set_max_lpc_order(0);
245*600f14f4SXin Li res = res || encoder.set_qlp_coeff_precision(0);
246*600f14f4SXin Li res = res || encoder.set_do_qlp_coeff_prec_search(true);
247*600f14f4SXin Li res = res || encoder.set_do_escape_coding(true);
248*600f14f4SXin Li res = res || encoder.set_min_residual_partition_order(0);
249*600f14f4SXin Li res = res || encoder.set_max_residual_partition_order(0);
250*600f14f4SXin Li res = res || encoder.set_rice_parameter_search_dist(0);
251*600f14f4SXin Li res = res || encoder.set_total_samples_estimate(0);
252*600f14f4SXin Li res = res || encoder.set_channels(channels);
253*600f14f4SXin Li res = res || encoder.set_bits_per_sample(16);
254*600f14f4SXin Li res = res || encoder.set_limit_min_bitrate(true);
255*600f14f4SXin Li res = res || encoder.set_blocksize(3021);
256*600f14f4SXin Li res = res || encoder.set_sample_rate(44100);
257*600f14f4SXin Li fuzzing::memory::memory_test(res);
258*600f14f4SXin Li if(res)
259*600f14f4SXin Li abort();
260*600f14f4SXin Li }
261*600f14f4SXin Li
262*600f14f4SXin Li
263*600f14f4SXin Li {
264*600f14f4SXin Li /* XORing values as otherwise compiler will optimize, apparently */
265*600f14f4SXin Li bool res = false;
266*600f14f4SXin Li res = res != encoder.get_streamable_subset();
267*600f14f4SXin Li res = res != encoder.get_verify();
268*600f14f4SXin Li res = res != encoder.get_do_exhaustive_model_search();
269*600f14f4SXin Li res = res != encoder.get_do_mid_side_stereo();
270*600f14f4SXin Li res = res != encoder.get_loose_mid_side_stereo();
271*600f14f4SXin Li res = res != encoder.get_max_lpc_order();
272*600f14f4SXin Li res = res != encoder.get_qlp_coeff_precision();
273*600f14f4SXin Li res = res != encoder.get_do_qlp_coeff_prec_search();
274*600f14f4SXin Li res = res != encoder.get_do_escape_coding();
275*600f14f4SXin Li res = res != encoder.get_min_residual_partition_order();
276*600f14f4SXin Li res = res != encoder.get_max_residual_partition_order();
277*600f14f4SXin Li res = res != encoder.get_rice_parameter_search_dist();
278*600f14f4SXin Li res = res != encoder.get_total_samples_estimate();
279*600f14f4SXin Li res = res != encoder.get_channels();
280*600f14f4SXin Li res = res != encoder.get_bits_per_sample();
281*600f14f4SXin Li res = res != encoder.get_limit_min_bitrate();
282*600f14f4SXin Li res = res != encoder.get_blocksize();
283*600f14f4SXin Li res = res != encoder.get_sample_rate();
284*600f14f4SXin Li fuzzing::memory::memory_test(res);
285*600f14f4SXin Li }
286*600f14f4SXin Li
287*600f14f4SXin Li decoder.process_until_end_of_stream();
288*600f14f4SXin Li
289*600f14f4SXin Li } catch ( ... ) { }
290*600f14f4SXin Li
291*600f14f4SXin Li end:
292*600f14f4SXin Li {
293*600f14f4SXin Li const bool res = encoder.finish();
294*600f14f4SXin Li fuzzing::memory::memory_test(res);
295*600f14f4SXin Li }
296*600f14f4SXin Li {
297*600f14f4SXin Li const bool res = decoder.finish();
298*600f14f4SXin Li fuzzing::memory::memory_test(res);
299*600f14f4SXin Li }
300*600f14f4SXin Li for(int i = 0; i < decoder.num_metadata_blocks; i++)
301*600f14f4SXin Li FLAC__metadata_object_delete(decoder.metadata_blocks[i]);
302*600f14f4SXin Li
303*600f14f4SXin Li return 0;
304*600f14f4SXin Li }
305