1#include <stdlib.h>
2#include <string.h>
3#include <sys/types.h>
4#include <sndfile.h>
5#include <inttypes.h>
6
7#include "sndfile_fuzz_header.h"
8
9extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
10{   // One byte is needed for deciding which function to target.
11    if (size == 0)
12       return 0 ;
13
14    const uint8_t decider = *data ;
15    data += 1 ;
16    size -= 1 ;
17
18    SF_INFO sndfile_info ;
19    VIO_DATA vio_data ;
20    SF_VIRTUAL_IO vio ;
21    SNDFILE *sndfile = NULL ;
22    int err = sf_init_file(data, size, &sndfile, &vio_data, &vio, &sndfile_info) ;
23    if (err)
24      goto EXIT_LABEL ;
25
26    // Just the right number of channels. Create some buffer space for reading.
27    switch (decider % 3)
28    {   case 0  :
29                {
30                  short* read_buffer = NULL ;
31                  read_buffer = (short*)malloc(sizeof(short) * size);
32                  if (read_buffer == NULL)
33                    abort() ;
34
35                  while (sf_read_short(sndfile, read_buffer, size))
36                  {
37                    // Do nothing with the data.
38                  }
39                  free(read_buffer) ;
40                }
41                break ;
42        case 1  :
43                {
44                  int* read_buffer = NULL ;
45                  read_buffer = (int*)malloc(sizeof(int) * size) ;
46                  if (read_buffer == NULL)
47                    abort() ;
48
49                  while (sf_read_int(sndfile, read_buffer, size))
50                  {
51                    // Do nothing with the data.
52                  }
53                  free(read_buffer) ;
54                }
55                break ;
56        case 2  :
57                {
58                  double* read_buffer = NULL ;
59                  read_buffer = (double*)malloc(sizeof(double) * size) ;
60                  if (read_buffer == NULL)
61                    abort() ;
62
63                  while (sf_read_double(sndfile, read_buffer, size))
64                  {
65                    // Do nothing with the data.
66                  }
67                  free(read_buffer) ;
68                }
69                break ;
70        default :
71                break ;
72                } ;
73
74  EXIT_LABEL:
75    if (sndfile != NULL)
76      sf_close(sndfile);
77
78    return 0 ;
79}
80