mirror of
https://gitee.com/openharmony/third_party_libsnd
synced 2024-11-23 01:49:53 +00:00
110e26d9c2
Adds a fuzzer targeting sf_read_double, sf_read_int and sf_read_short. Co-authored-by: evpobr <evpobr@gmail.com>
120 lines
2.8 KiB
C
120 lines
2.8 KiB
C
#ifndef SNDFILE_FUZZ_HEADER_H
|
|
#define SNDFILE_FUZZ_HEADER_H
|
|
|
|
typedef struct
|
|
{
|
|
sf_count_t offset ;
|
|
sf_count_t length ;
|
|
const unsigned char *data ;
|
|
} VIO_DATA ;
|
|
|
|
static sf_count_t vfget_filelen (void *user_data)
|
|
{ VIO_DATA *vf = (VIO_DATA *)user_data ;
|
|
return vf->length ;
|
|
}
|
|
|
|
static sf_count_t vfseek (sf_count_t offset, int whence, void *user_data)
|
|
{
|
|
VIO_DATA *vf = (VIO_DATA *)user_data ;
|
|
sf_count_t new_offset ;
|
|
|
|
switch (whence)
|
|
{ case SEEK_SET :
|
|
new_offset = offset ;
|
|
break ;
|
|
|
|
case SEEK_CUR :
|
|
new_offset = vf->offset + offset ;
|
|
break ;
|
|
|
|
case SEEK_END :
|
|
new_offset = vf->length + offset ;
|
|
break ;
|
|
|
|
default :
|
|
break ;
|
|
}
|
|
|
|
/* Ensure you can't seek outside the data */
|
|
if (new_offset > vf->length)
|
|
{ /* Trying to seek past the end of the data */
|
|
printf("vf overseek: new_offset(%" PRId64 ") > vf->length(%" PRId64 ");"
|
|
" whence(%d), vf->offset(%" PRId64 "), offset(%" PRId64 ")\n",
|
|
new_offset, vf->length, whence, vf->offset, offset) ;
|
|
new_offset = vf->length ;
|
|
}
|
|
else if (new_offset < 0)
|
|
{ /* Trying to seek before the start of the data */
|
|
printf("vf underseek: new_offset(%" PRId64 ") < 0; whence(%d), vf->offset"
|
|
"(%" PRId64 "), vf->length(%" PRId64 "), offset(%" PRId64 ")\n",
|
|
new_offset, whence, vf->offset, vf->length, offset) ;
|
|
new_offset = 0 ;
|
|
}
|
|
vf->offset = new_offset ;
|
|
|
|
return vf->offset ;
|
|
}
|
|
|
|
static sf_count_t vfread (void *ptr, sf_count_t count, void *user_data)
|
|
{ VIO_DATA *vf = (VIO_DATA *)user_data ;
|
|
|
|
if (vf->offset + count > vf->length)
|
|
count = vf->length - vf->offset ;
|
|
|
|
memcpy(ptr, vf->data + vf->offset, count) ;
|
|
vf->offset += count ;
|
|
|
|
return count ;
|
|
}
|
|
|
|
static sf_count_t vfwrite (const void *ptr, sf_count_t count, void *user_data)
|
|
{
|
|
(void)ptr ;
|
|
(void)count ;
|
|
(void)user_data ;
|
|
|
|
// Cannot write to this virtual file.
|
|
return 0;
|
|
}
|
|
|
|
static sf_count_t vftell (void *user_data)
|
|
{ VIO_DATA *vf = (VIO_DATA *)user_data ;
|
|
|
|
return vf->offset ;
|
|
}
|
|
|
|
int sf_init_file(const uint8_t *data,
|
|
size_t size,
|
|
SNDFILE **sndfile,
|
|
VIO_DATA *vio_data,
|
|
SF_VIRTUAL_IO *vio, SF_INFO *sndfile_info)
|
|
{ float* read_buffer = NULL ;
|
|
|
|
// Initialize the virtual IO structure.
|
|
vio->get_filelen = vfget_filelen ;
|
|
vio->seek = vfseek ;
|
|
vio->read = vfread ;
|
|
vio->write = vfwrite ;
|
|
vio->tell = vftell ;
|
|
|
|
// Initialize the VIO user data.
|
|
vio_data->data = data ;
|
|
vio_data->length = size ;
|
|
vio_data->offset = 0 ;
|
|
|
|
memset(sndfile_info, 0, sizeof(SF_INFO)) ;
|
|
|
|
// Try and open the virtual file.
|
|
*sndfile = sf_open_virtual(vio, SFM_READ, sndfile_info, vio_data) ;
|
|
|
|
if (sndfile_info->channels == 0)
|
|
return -1 ;
|
|
|
|
if (sndfile_info->channels > 1024 * 1024)
|
|
return -1 ;
|
|
|
|
return 0;
|
|
}
|
|
|
|
#endif
|