Add new decoder fuzzer, mostly to cover seeking
This second decoder fuzzer dumps the fuzz input to a file, which enables testing of seeking code
This commit is contained in:
parent
78d85dd4e4
commit
81c973fa1c
1
.gitignore
vendored
1
.gitignore
vendored
@ -77,6 +77,7 @@ test/picture.log
|
||||
microbench/benchmark_residual
|
||||
/ogg/
|
||||
oss-fuzz/fuzzer_decoder
|
||||
oss-fuzz/fuzzer_seek
|
||||
oss-fuzz/fuzzer_encoder
|
||||
oss-fuzz/fuzzer_encoder_v2
|
||||
|
||||
|
@ -31,7 +31,7 @@ EXTRA_DIST = \
|
||||
noinst_PROGRAMS =
|
||||
|
||||
if USE_OSSFUZZERS
|
||||
noinst_PROGRAMS += fuzzer_encoder fuzzer_encoder_v2 fuzzer_decoder
|
||||
noinst_PROGRAMS += fuzzer_encoder fuzzer_encoder_v2 fuzzer_decoder fuzzer_seek
|
||||
endif
|
||||
|
||||
fuzzer_encoder_SOURCES = fuzzer_encoder.cc
|
||||
@ -49,6 +49,12 @@ fuzzer_decoder_CXXFLAGS = $(AM_CXXFLAGS) $(LIB_FUZZING_ENGINE)
|
||||
fuzzer_decoder_LDFLAGS = $(AM_LDFLAGS)
|
||||
fuzzer_decoder_LDADD = $(flac_libs)
|
||||
|
||||
fuzzer_seek_SOURCES = fuzzer_seek.cc
|
||||
fuzzer_seek_CXXFLAGS = $(AM_CXXFLAGS) $(LIB_FUZZING_ENGINE)
|
||||
fuzzer_seek_LDFLAGS = $(AM_LDFLAGS)
|
||||
fuzzer_seek_LDADD = $(flac_libs)
|
||||
|
||||
|
||||
flac_libs = \
|
||||
$(top_builddir)/src/libFLAC/libFLAC-static.la \
|
||||
$(top_builddir)/src/libFLAC++/libFLAC++-static.la \
|
||||
|
172
oss-fuzz/fuzzer_seek.cc
Normal file
172
oss-fuzz/fuzzer_seek.cc
Normal file
@ -0,0 +1,172 @@
|
||||
/* fuzzer_seek
|
||||
* Copyright (C) 2022 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring> /* for memcpy */
|
||||
#include "FLAC/stream_decoder.h"
|
||||
|
||||
#if 0 /* set to 1 to debug */
|
||||
#define FPRINTF_DEBUG_ONLY(...) fprintf(__VA_ARGS__)
|
||||
#else
|
||||
#define FPRINTF_DEBUG_ONLY(...)
|
||||
#endif
|
||||
|
||||
#define CONFIG_LENGTH 1
|
||||
|
||||
static FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *const buffer[], void *client_data)
|
||||
{
|
||||
(void)decoder, (void)frame, (void)buffer, (void)client_data;
|
||||
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
static void error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus error, void *client_data)
|
||||
{
|
||||
(void)decoder, (void)error, (void)client_data;
|
||||
}
|
||||
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
FLAC__bool decoder_valid = true;
|
||||
FLAC__StreamDecoder *decoder;
|
||||
uint8_t command_length;
|
||||
FLAC__bool init_bools[16], ogg;
|
||||
|
||||
/* allocate the decoder */
|
||||
if((decoder = FLAC__stream_decoder_new()) == NULL) {
|
||||
fprintf(stderr, "ERROR: allocating decoder\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Use first byte for configuration, leave at least one byte of input */
|
||||
if(size < 1 + CONFIG_LENGTH){
|
||||
FLAC__stream_decoder_delete(decoder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* First 4 bits for configuration bools, next 4 for length of command section */
|
||||
for(int i = 0; i < 4; i++)
|
||||
init_bools[i] = data[i/8] & (1 << (i % 8));
|
||||
|
||||
command_length = data[0] >> 4;
|
||||
|
||||
/* Leave at least one byte as input */
|
||||
if(command_length >= size - 1 - CONFIG_LENGTH)
|
||||
command_length = size - 1 - CONFIG_LENGTH;
|
||||
|
||||
/* Dump decoder input to file */
|
||||
{
|
||||
FILE * file_to_decode = fopen("/tmp/tmp.flac","w");
|
||||
fwrite(data+CONFIG_LENGTH+command_length,1,size-CONFIG_LENGTH-command_length,file_to_decode);
|
||||
fclose(file_to_decode);
|
||||
}
|
||||
|
||||
ogg = init_bools[0];
|
||||
|
||||
FLAC__stream_decoder_set_md5_checking(decoder,init_bools[1]);
|
||||
if(init_bools[2])
|
||||
FLAC__stream_decoder_set_metadata_respond_all(decoder);
|
||||
if(init_bools[3])
|
||||
FLAC__stream_decoder_set_metadata_ignore_all(decoder);
|
||||
|
||||
/* initialize decoder */
|
||||
if(decoder_valid) {
|
||||
FLAC__StreamDecoderInitStatus init_status;
|
||||
if(ogg)
|
||||
init_status = FLAC__stream_decoder_init_ogg_file(decoder, "/tmp/tmp.flac", write_callback, NULL, error_callback, NULL);
|
||||
else
|
||||
init_status = FLAC__stream_decoder_init_file(decoder, "/tmp/tmp.flac", write_callback, NULL, error_callback, NULL);
|
||||
if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
|
||||
decoder_valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Run commands */
|
||||
for(uint8_t i = 0; decoder_valid && (i < command_length); i++){
|
||||
const uint8_t * command = data+CONFIG_LENGTH+i;
|
||||
uint8_t shift = 1u << (command[0] >> 3);
|
||||
FLAC__uint64 seekpos;
|
||||
|
||||
switch(command[0] & 7){
|
||||
case 0:
|
||||
FPRINTF_DEBUG_ONLY(stderr,"end_of_stream\n");
|
||||
decoder_valid = FLAC__stream_decoder_process_until_end_of_stream(decoder);
|
||||
break;
|
||||
case 1:
|
||||
FPRINTF_DEBUG_ONLY(stderr,"end_of_metadata\n");
|
||||
decoder_valid = FLAC__stream_decoder_process_until_end_of_metadata(decoder);
|
||||
break;
|
||||
case 2:
|
||||
FPRINTF_DEBUG_ONLY(stderr,"single\n");
|
||||
decoder_valid = FLAC__stream_decoder_process_single(decoder);
|
||||
break;
|
||||
case 3:
|
||||
FPRINTF_DEBUG_ONLY(stderr,"skip_single\n");
|
||||
decoder_valid = FLAC__stream_decoder_skip_single_frame(decoder);
|
||||
break;
|
||||
case 4:
|
||||
FPRINTF_DEBUG_ONLY(stderr,"reset\n");
|
||||
decoder_valid = FLAC__stream_decoder_reset(decoder);
|
||||
break;
|
||||
case 5:
|
||||
FPRINTF_DEBUG_ONLY(stderr,"flush\n");
|
||||
decoder_valid = FLAC__stream_decoder_flush(decoder);
|
||||
break;
|
||||
case 6:
|
||||
shift = 1u << (command[0] >> 3);
|
||||
FPRINTF_DEBUG_ONLY(stderr,"seek short %hhu\n",shift);
|
||||
decoder_valid = FLAC__stream_decoder_seek_absolute(decoder,shift);
|
||||
break;
|
||||
case 7:
|
||||
if(i+8 >= command_length) /* Not enough data available to do this */
|
||||
break;
|
||||
seekpos = ((FLAC__uint64)command[1] << 56) +
|
||||
((FLAC__uint64)command[2] << 48) +
|
||||
((FLAC__uint64)command[3] << 40) +
|
||||
((FLAC__uint64)command[4] << 32) +
|
||||
((FLAC__uint64)command[5] << 24) +
|
||||
((FLAC__uint64)command[6] << 16) +
|
||||
((FLAC__uint64)command[7] << 8) +
|
||||
command[8];
|
||||
i+=8;
|
||||
FPRINTF_DEBUG_ONLY(stderr,"seek long %lu\n",seekpos);
|
||||
decoder_valid = FLAC__stream_decoder_seek_absolute(decoder,seekpos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FLAC__stream_decoder_finish(decoder);
|
||||
|
||||
FLAC__stream_decoder_delete(decoder);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user