88 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			88 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
	
| #include <stddef.h>
 | |
| #include <unistd.h>
 | |
| #include <stdint.h>
 | |
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| #include <stdbool.h>
 | |
| #include <string.h>
 | |
| 
 | |
| #include "mpg123.h"
 | |
| 
 | |
| static char* fuzzer_get_tmpfile(const uint8_t* data, size_t size) {
 | |
|   char* filename_buffer = strdup("/tmp/generate_temporary_file.XXXXXX");
 | |
|   if (!filename_buffer) {
 | |
|     perror("Failed to allocate file name buffer.");
 | |
|     abort();
 | |
|   }
 | |
|   const int file_descriptor = mkstemp(filename_buffer);
 | |
|   if (file_descriptor < 0) {
 | |
|     perror("Failed to make temporary file.");
 | |
|     abort();
 | |
|   }
 | |
|   FILE* file = fdopen(file_descriptor, "wb");
 | |
|   if (!file) {
 | |
|     perror("Failed to open file descriptor.");
 | |
|     close(file_descriptor);
 | |
|     abort();
 | |
|   }
 | |
|   const size_t bytes_written = fwrite(data, sizeof(uint8_t), size, file);
 | |
|   if (bytes_written < size) {
 | |
|     close(file_descriptor);
 | |
|     fprintf(stderr, "Failed to write all bytes to file (%zu out of %zu)",
 | |
|             bytes_written, size);
 | |
|     abort();
 | |
|   }
 | |
|   fclose(file);
 | |
|   return filename_buffer;
 | |
| }
 | |
| 
 | |
| static void fuzzer_release_tmpfile(char* filename) {
 | |
|   if (unlink(filename) != 0) {
 | |
|     perror("WARNING: Failed to delete temporary file.");
 | |
|   }
 | |
|   free(filename);
 | |
| }
 | |
| 
 | |
| int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
 | |
|   static bool initialized = false;
 | |
|   if (!initialized) {
 | |
|     mpg123_init();
 | |
|     initialized = true;
 | |
|   }
 | |
|   char* filename = fuzzer_get_tmpfile(data, size);
 | |
|   if (filename == NULL) {
 | |
|     return 0;
 | |
|   }
 | |
| 
 | |
|   size_t outmemorysize = size * 2;  // Guess based on the size of data.
 | |
|   unsigned char* outmemory = (unsigned char*)malloc(outmemorysize);
 | |
|   if (outmemory == NULL) {
 | |
|     fuzzer_release_tmpfile(filename);
 | |
|     return 0;
 | |
|   }
 | |
| 
 | |
|   int error;
 | |
|   mpg123_handle* handle = mpg123_new(NULL, &error);
 | |
|   if (handle == NULL || mpg123_param(handle,
 | |
|       MPG123_ADD_FLAGS, MPG123_QUIET, 0.) != MPG123_OK) {
 | |
|     free(outmemory);
 | |
|     fuzzer_release_tmpfile(filename);
 | |
|     return 0;
 | |
|   }
 | |
| 
 | |
|   if (mpg123_open(handle, filename) == MPG123_OK) {
 | |
|     int read_error;
 | |
|     do {
 | |
|       size_t decoded_size;
 | |
|       read_error = mpg123_read(handle, outmemory, outmemorysize, &decoded_size);
 | |
|     } while (read_error == MPG123_OK && mpg123_tellframe(handle) <= 10000
 | |
|           && mpg123_tell_stream(handle) <= 1<<20);
 | |
|   }
 | |
| 
 | |
|   mpg123_close(handle);
 | |
|   mpg123_delete(handle);
 | |
|   free(outmemory);
 | |
|   fuzzer_release_tmpfile(filename);
 | |
|   return 0;
 | |
| }
 |