1 #include <stddef.h>
2 #include <unistd.h>
3 #include <stdint.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <stdbool.h>
7 #include <string.h>
8
9 #include "mpg123.h"
10
fuzzer_get_tmpfile(const uint8_t * data,size_t size)11 static char* fuzzer_get_tmpfile(const uint8_t* data, size_t size) {
12 char* filename_buffer = strdup("/tmp/generate_temporary_file.XXXXXX");
13 if (!filename_buffer) {
14 perror("Failed to allocate file name buffer.");
15 abort();
16 }
17 const int file_descriptor = mkstemp(filename_buffer);
18 if (file_descriptor < 0) {
19 perror("Failed to make temporary file.");
20 abort();
21 }
22 FILE* file = fdopen(file_descriptor, "wb");
23 if (!file) {
24 perror("Failed to open file descriptor.");
25 close(file_descriptor);
26 abort();
27 }
28 const size_t bytes_written = fwrite(data, sizeof(uint8_t), size, file);
29 if (bytes_written < size) {
30 close(file_descriptor);
31 fprintf(stderr, "Failed to write all bytes to file (%zu out of %zu)",
32 bytes_written, size);
33 abort();
34 }
35 fclose(file);
36 return filename_buffer;
37 }
38
fuzzer_release_tmpfile(char * filename)39 static void fuzzer_release_tmpfile(char* filename) {
40 if (unlink(filename) != 0) {
41 perror("WARNING: Failed to delete temporary file.");
42 }
43 free(filename);
44 }
45
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)46 int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
47 static bool initialized = false;
48 if (!initialized) {
49 mpg123_init();
50 initialized = true;
51 }
52 char* filename = fuzzer_get_tmpfile(data, size);
53 if (filename == NULL) {
54 return 0;
55 }
56
57 size_t outmemorysize = size * 2; // Guess based on the size of data.
58 unsigned char* outmemory = (unsigned char*)malloc(outmemorysize);
59 if (outmemory == NULL) {
60 fuzzer_release_tmpfile(filename);
61 return 0;
62 }
63
64 int error;
65 mpg123_handle* handle = mpg123_new(NULL, &error);
66 if (handle == NULL || mpg123_param(handle,
67 MPG123_ADD_FLAGS, MPG123_QUIET, 0.) != MPG123_OK) {
68 free(outmemory);
69 fuzzer_release_tmpfile(filename);
70 return 0;
71 }
72
73 if (mpg123_open(handle, filename) == MPG123_OK) {
74 int read_error;
75 do {
76 size_t decoded_size;
77 read_error = mpg123_read(handle, outmemory, outmemorysize, &decoded_size);
78 } while (read_error == MPG123_OK && mpg123_tellframe(handle) <= 10000
79 && mpg123_tell_stream(handle) <= 1<<20);
80 }
81
82 mpg123_close(handle);
83 mpg123_delete(handle);
84 free(outmemory);
85 fuzzer_release_tmpfile(filename);
86 return 0;
87 }
88