1 #ifndef SNDFILE_FUZZ_HEADER_H
2 #define SNDFILE_FUZZ_HEADER_H
3 
4 typedef struct
5 {
6   sf_count_t offset ;
7   sf_count_t length ;
8   const unsigned char *data ;
9 } VIO_DATA ;
10 
vfget_filelen(void *user_data)11 static sf_count_t vfget_filelen (void *user_data)
12 {  VIO_DATA *vf = (VIO_DATA *)user_data ;
13    return vf->length ;
14 }
15 
vfseek(sf_count_t offset, int whence, void *user_data)16 static sf_count_t vfseek (sf_count_t offset, int whence, void *user_data)
17 {
18   VIO_DATA *vf = (VIO_DATA *)user_data ;
19   sf_count_t new_offset ;
20 
21   switch (whence)
22   {   case SEEK_SET :
23         new_offset = offset ;
24         break ;
25 
26     case SEEK_CUR :
27         new_offset = vf->offset + offset ;
28         break ;
29 
30     case SEEK_END :
31         new_offset = vf->length + offset ;
32         break ;
33 
34     default :
35         break ;
36   }
37 
38   /* Ensure you can't seek outside the data */
39   if (new_offset > vf->length)
40   {  /* Trying to seek past the end of the data */
41      printf("vf overseek: new_offset(%" PRId64 ") > vf->length(%" PRId64 ");"
42             "  whence(%d), vf->offset(%" PRId64 "), offset(%" PRId64 ")\n",
43             new_offset, vf->length, whence, vf->offset, offset) ;
44      new_offset = vf->length ;
45   }
46   else if (new_offset < 0)
47   {  /* Trying to seek before the start of the data */
48      printf("vf underseek: new_offset(%" PRId64 ") < 0;  whence(%d), vf->offset"
49             "(%" PRId64 "), vf->length(%" PRId64 "), offset(%" PRId64 ")\n",
50             new_offset, whence, vf->offset, vf->length, offset) ;
51      new_offset = 0 ;
52   }
53   vf->offset = new_offset ;
54 
55   return vf->offset ;
56 }
57 
vfread(void *ptr, sf_count_t count, void *user_data)58 static sf_count_t vfread (void *ptr, sf_count_t count, void *user_data)
59 {  VIO_DATA *vf = (VIO_DATA *)user_data ;
60 
61    if (vf->offset + count > vf->length)
62      count = vf->length - vf->offset ;
63 
64    memcpy(ptr, vf->data + vf->offset, count) ;
65    vf->offset += count ;
66 
67    return count ;
68 }
69 
vfwrite(const void *ptr, sf_count_t count, void *user_data)70 static sf_count_t vfwrite (const void *ptr, sf_count_t count, void *user_data)
71 {
72   (void)ptr ;
73   (void)count ;
74   (void)user_data ;
75 
76   // Cannot write to this virtual file.
77   return 0;
78 }
79 
vftell(void *user_data)80 static sf_count_t vftell (void *user_data)
81 { VIO_DATA *vf = (VIO_DATA *)user_data ;
82 
83   return vf->offset ;
84 }
85 
sf_init_file(const uint8_t *data, size_t size, SNDFILE **sndfile, VIO_DATA *vio_data, SF_VIRTUAL_IO *vio, SF_INFO *sndfile_info)86 int sf_init_file(const uint8_t *data,
87                 size_t size,
88                 SNDFILE **sndfile,
89                 VIO_DATA *vio_data,
90                 SF_VIRTUAL_IO *vio, SF_INFO *sndfile_info)
91 {  float* read_buffer = NULL ;
92 
93    // Initialize the virtual IO structure.
94    vio->get_filelen = vfget_filelen ;
95    vio->seek = vfseek ;
96    vio->read = vfread ;
97    vio->write = vfwrite ;
98    vio->tell = vftell ;
99 
100    // Initialize the VIO user data.
101    vio_data->data = data ;
102    vio_data->length = size ;
103    vio_data->offset = 0 ;
104 
105    memset(sndfile_info, 0, sizeof(SF_INFO)) ;
106 
107    // Try and open the virtual file.
108    *sndfile = sf_open_virtual(vio, SFM_READ, sndfile_info, vio_data) ;
109 
110    if (sndfile_info->channels == 0)
111 		 return -1 ;
112 
113    if (sndfile_info->channels > 1024 * 1024)
114 		 return -1 ;
115 
116    return 0;
117 }
118 
119 #endif
120