Coverage Report

Created: 2026-03-31 06:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/bzip2_fd.c
Line
Count
Source
1
/*
2
# Copyright 2022 Google LLC
3
#
4
# Licensed under the Apache License, Version 2.0 (the "License");
5
# you may not use this file except in compliance with the License.
6
# You may obtain a copy of the License at
7
#
8
#      http://www.apache.org/licenses/LICENSE-2.0
9
#
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS,
12
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
# See the License for the specific language governing permissions and
14
# limitations under the License.
15
#
16
###############################################################################
17
*/
18
19
#include "bzlib.h"
20
#include <stdint.h>
21
#include <stdlib.h>
22
#include <string.h>
23
#include <unistd.h>
24
#include <stdio.h>
25
#include <fcntl.h>
26
27
3.14k
static void fuzzer_write_data(FILE *file, const uint8_t *data, size_t size) {
28
3.14k
  int    bzerr         = 0;
29
3.14k
  int    blockSize100k = 9;
30
3.14k
  int    verbosity     = 0;
31
3.14k
  int    workFactor    = 30;
32
3.14k
  unsigned int nbytes_in_lo32, nbytes_in_hi32;
33
3.14k
  unsigned int nbytes_out_lo32, nbytes_out_hi32;
34
35
3.14k
  BZFILE* bzf = BZ2_bzWriteOpen(&bzerr, file,
36
3.14k
                           blockSize100k, verbosity, workFactor);
37
3.14k
  if (bzerr != BZ_OK) return;
38
39
  /* Use low-level BZ2_bzWrite (was incorrectly using high-level BZ2_bzwrite) */
40
3.14k
  BZ2_bzWrite(&bzerr, bzf, (void*)data, size);
41
42
3.14k
  BZ2_bzWriteClose64(&bzerr, bzf, 0,
43
3.14k
                      &nbytes_in_lo32, &nbytes_in_hi32,
44
3.14k
                      &nbytes_out_lo32, &nbytes_out_hi32);
45
3.14k
}
46
47
3.14k
static void fuzzer_read_data(const int file_descriptor) {
48
3.14k
  int    bzerr         = 0;
49
3.14k
  char   obuf[BZ_MAX_UNUSED];
50
51
3.14k
  BZFILE* bzf2 = BZ2_bzdopen(file_descriptor, "rb");
52
3.14k
  if (!bzf2) return;
53
54
49.3k
  while (bzerr == BZ_OK) {
55
46.2k
      int nread = BZ2_bzRead(&bzerr, bzf2, obuf, BZ_MAX_UNUSED);
56
46.2k
      if (nread == 0 && bzerr == BZ_OK) break;
57
46.2k
  }
58
59
3.14k
  BZ2_bzclose(bzf2);
60
3.14k
}
61
62
int
63
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
64
3.14k
{
65
3.14k
  char* filename = strdup("/tmp/generate_temporary_file.XXXXXX");
66
3.14k
  if (!filename) {
67
0
    return 0;
68
0
  }
69
3.14k
  const int file_descriptor = mkstemp(filename);
70
3.14k
  if (file_descriptor < 0) {
71
0
    free(filename);
72
0
    return 0;
73
0
  }
74
3.14k
  FILE* file = fdopen(file_descriptor, "wb");
75
76
3.14k
  if (!file) {
77
0
    close(file_descriptor);
78
0
    free(filename);
79
0
    return 0;
80
0
  }
81
82
3.14k
  fuzzer_write_data(file, data, size);
83
84
3.14k
  fflush(file);
85
86
3.14k
  int read_fd = open(filename, O_RDONLY);
87
3.14k
  if (read_fd >= 0) {
88
3.14k
    fuzzer_read_data(read_fd);
89
3.14k
  }
90
91
  /* Removed BZ2_bzflush(file) - it expects BZFILE*, not FILE* */
92
3.14k
  fclose(file);
93
94
3.14k
  unlink(filename);
95
3.14k
  free(filename);
96
3.14k
  return 0;
97
3.14k
}