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
							 |