Coverage Report

Created: 2025-07-11 06:37

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