Coverage Report

Created: 2025-06-15 00:57

/src/cmp_tool/test/fuzz/fuzz_round_trip.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * @file fuzz_round_trip.c
3
 * @date 2024
4
 *
5
 * @copyright GPLv2
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms and conditions of the GNU General Public License,
8
 * version 2, as published by the Free Software Foundation.
9
 *
10
 * This program is distributed in the hope it will be useful, but WITHOUT
11
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13
 * more details.
14
 *
15
 * @brief chunk compression/decompression fuzz target
16
 *
17
 * This fuzzer tests the (de)compression functionality with random data/model
18
 * and parameters. It uses a random portion of the input data for parameter
19
 * generation, while the rest is used for compression. If the compression
20
 * succeeds, the data are decompressed and checked to see whether they match the
21
 * input data.
22
 */
23
24
#include <string.h>
25
#include <stdlib.h>
26
27
#include "fuzz_helpers.h"
28
#include "fuzz_data_producer.h"
29
#include "../test_common/chunk_round_trip.h"
30
31
32
int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
33
2.70k
{
34
2.70k
  struct cmp_par cmp_par;
35
2.70k
  struct cmp_par *cmp_par_ptr = NULL;
36
2.70k
  const uint8_t *model = NULL;
37
2.70k
  void *up_model = NULL;
38
2.70k
  uint32_t cmp_size_bound;
39
2.70k
  uint32_t *cmp_data;
40
2.70k
  uint32_t cmp_data_capacity;
41
2.70k
  uint32_t return_value;
42
2.70k
  int use_decmp_buf;
43
2.70k
  int use_decmp_up_model;
44
45
  /* Give a random portion of src data to the producer, to use for
46
     parameter generation. The rest will be used for (de)compression */
47
2.70k
  FUZZ_dataProducer_t *producer = (FUZZ_dataProducer_t *)FUZZ_dataProducer_create(src, size);
48
49
2.70k
  size = FUZZ_dataProducer_reserveDataPrefix(producer);
50
51
  /* 1/2 of the cases we use a model */
52
2.70k
  if (FUZZ_dataProducer_uint32Range(producer, 0, 1) && size > 2) {
53
1.37k
    model = src + size/2;
54
1.37k
    size /= 2;
55
1.37k
  }
56
2.70k
  FUZZ_ASSERT(size <= UINT32_MAX);
57
58
  /* generate compression parameters */
59
2.70k
  FUZZ_dataProducer_cmp_par(producer, &cmp_par);
60
2.70k
  if (FUZZ_dataProducer_uint32Range(producer, 0, 1))
61
2.56k
    cmp_par_ptr = &cmp_par;
62
63
  /* 1/2 of the cases we use a updated model buffer */
64
2.70k
  if (FUZZ_dataProducer_uint32Range(producer, 0, 1)) {
65
1.99k
    up_model = FUZZ_malloc(size);
66
1.99k
    if (!model_mode_is_used(cmp_par.cmp_mode))
67
753
      memset(up_model, 0, size); /* up_model is not used */
68
1.99k
  }
69
70
2.70k
  cmp_size_bound = compress_chunk_cmp_size_bound(src, size);
71
2.70k
  if (cmp_is_error(cmp_size_bound))
72
543
    cmp_size_bound = 0;
73
2.70k
  cmp_data_capacity = FUZZ_dataProducer_uint32Range(producer, 0, cmp_size_bound+(uint32_t)size);
74
2.70k
  cmp_data = (uint32_t *)FUZZ_malloc(cmp_data_capacity);
75
76
2.70k
  use_decmp_buf = FUZZ_dataProducer_int32Range(producer, 0, 1);
77
2.70k
  use_decmp_up_model = FUZZ_dataProducer_int32Range(producer, 0, 1);
78
79
2.70k
  return_value = chunk_round_trip(src, (uint32_t)size, model, up_model, cmp_data,
80
2.70k
          cmp_data_capacity, cmp_par_ptr,
81
2.70k
          use_decmp_buf, use_decmp_up_model);
82
2.70k
  switch (cmp_get_error_code(return_value)) {
83
1.65k
  case CMP_ERROR_NO_ERROR:
84
1.65k
  case CMP_ERROR_GENERIC:
85
1.88k
  case CMP_ERROR_SMALL_BUFFER:
86
  /* compression parameter errors */
87
1.89k
  case CMP_ERROR_PAR_GENERIC:
88
1.92k
  case CMP_ERROR_PAR_SPECIFIC:
89
1.92k
  case CMP_ERROR_PAR_BUFFERS:
90
2.06k
  case CMP_ERROR_PAR_NULL:
91
2.06k
  case CMP_ERROR_PAR_NO_MODEL:
92
  /* chunk errors */
93
2.06k
  case CMP_ERROR_CHUNK_NULL:
94
2.06k
  case CMP_ERROR_CHUNK_TOO_LARGE:
95
2.06k
  case CMP_ERROR_CHUNK_TOO_SMALL:
96
2.24k
  case CMP_ERROR_CHUNK_SIZE_INCONSISTENT:
97
2.47k
  case CMP_ERROR_CHUNK_SUBSERVICE_INCONSISTENT:
98
  /* collection errors */
99
2.47k
  case CMP_ERROR_COL_SUBSERVICE_UNSUPPORTED:
100
2.47k
  case CMP_ERROR_COL_SIZE_INCONSISTENT:
101
2.47k
    break;
102
  /* compression entity errors */
103
0
  case CMP_ERROR_ENTITY_NULL:
104
0
    FUZZ_ASSERT(0);
105
0
  case CMP_ERROR_ENTITY_TOO_SMALL:
106
0
    FUZZ_ASSERT(0);
107
230
  case CMP_ERROR_ENTITY_HEADER:
108
230
    break;
109
0
  case CMP_ERROR_ENTITY_TIMESTAMP:
110
0
    FUZZ_ASSERT(0);
111
  /* internal compressor errors */
112
0
  case CMP_ERROR_INT_DECODER:
113
0
    FUZZ_ASSERT(0);
114
0
  case CMP_ERROR_INT_DATA_TYPE_UNSUPPORTED:
115
0
    FUZZ_ASSERT(0);
116
0
  case CMP_ERROR_INT_CMP_COL_TOO_LARGE:
117
0
    FUZZ_ASSERT(0);
118
119
0
  case CMP_ERROR_DATA_VALUE_TOO_LARGE:
120
0
    FUZZ_ASSERT(0);
121
0
  default:
122
0
    FUZZ_ASSERT(0);
123
2.70k
  }
124
125
2.70k
  free(up_model);
126
2.70k
  free(cmp_data);
127
2.70k
  FUZZ_dataProducer_free(producer);
128
129
2.70k
  return 0;
130
2.70k
}