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
 |