Coverage Report

Created: 2025-07-18 06:49

/src/c-blosc2/tests/fuzz/fuzz_compress_frame.c
Line
Count
Source (jump to first uncovered line)
1
#include <stdint.h>
2
#include <stdlib.h>
3
#include <stdio.h>
4
#include <inttypes.h>
5
6
#include <blosc2.h>
7
8
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
9
10
#ifdef __cplusplus
11
extern "C" {
12
#endif
13
14
2.29k
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
15
2.29k
  const char *const compressors[] = { "blosclz", "lz4", "lz4hc", "zlib", "zstd" };
16
2.29k
  int32_t i = 0, dsize = 0, filter = BLOSC_BITSHUFFLE;
17
2.29k
  int32_t nchunk = 0, max_chunksize = 512;
18
2.29k
  int64_t nchunks = 0;
19
20
2.29k
  blosc2_init();
21
22
2.29k
  blosc2_cparams cparams = BLOSC2_CPARAMS_DEFAULTS;
23
2.29k
  cparams.typesize = 1;
24
  /* Find next available compressor */
25
2.29k
  cparams.compcode = 0;
26
2.29k
  while (blosc1_set_compressor(compressors[cparams.compcode % 6]) == -1 && i < 6) {
27
0
    cparams.compcode++, i++;
28
0
  }
29
2.29k
  if (i == 6) {
30
    /* No compressors available */
31
0
    blosc2_destroy();
32
0
    return 0;
33
0
  }
34
2.29k
  if (size > INT32_MAX) {
35
0
      printf("Conversion error: size_t does not fit in int32_t\n");
36
0
      return 0;
37
0
  }
38
2.29k
  if (size > 0) {
39
    /* Variable size compression level and max chunksize */
40
2.29k
    cparams.clevel = data[0] % (9 + 1);
41
2.29k
    max_chunksize *= data[0];
42
2.29k
  }
43
2.29k
  if (size > 1) {
44
2.27k
    filter = data[1];
45
2.27k
  }
46
2.29k
  cparams.filters[BLOSC2_MAX_FILTERS - 1] = filter % (BLOSC_BITSHUFFLE + 1);
47
2.29k
  cparams.filters_meta[BLOSC2_MAX_FILTERS - 1] = filter;
48
2.29k
  cparams.nthreads = 1;
49
50
2.29k
  blosc2_dparams dparams = BLOSC2_DPARAMS_DEFAULTS;
51
2.29k
  dparams.nthreads = 1;
52
53
  /* Create a super-chunk backed by an in-memory frame */
54
2.29k
  blosc2_storage storage = {.cparams=&cparams, .dparams=&dparams};
55
2.29k
  blosc2_schunk* schunk = blosc2_schunk_new(&storage);
56
2.29k
  if (schunk == NULL) {
57
0
    blosc2_destroy();
58
0
    return 0;
59
0
  }
60
61
  /* Compress data */
62
2.29k
  int32_t chunksize = max_chunksize;
63
43.9k
  for (i = 0; chunksize > 0 && i < (int32_t)size; i += chunksize, nchunks++) {
64
41.6k
    if (i + chunksize > (int32_t)size)
65
2.08k
      chunksize = (int32_t)size - i;
66
41.6k
    nchunks = blosc2_schunk_append_buffer(schunk, (uint8_t *)data + i, chunksize);
67
41.6k
    if (nchunks < 0) {
68
0
      printf("Compression error.  Error code: %" PRId64 "\n", nchunks);
69
0
      break;
70
0
    }
71
41.6k
  }
72
73
  /* Decompress data */
74
2.29k
  uint8_t *uncompressed_data = (uint8_t *)malloc(size+1);
75
2.29k
  if (uncompressed_data != NULL) {
76
15.7k
    for (i = 0, nchunk = 0; nchunk < nchunks-1; nchunk++) {
77
13.8k
      dsize = blosc2_schunk_decompress_chunk(schunk, nchunk, uncompressed_data + i, chunksize);
78
13.8k
      if (dsize < 0) {
79
416
        printf("Decompression error.  Error code: %d\n", dsize);
80
416
        break;
81
416
      }
82
13.4k
      i += dsize;
83
13.4k
    }
84
85
    /* Compare decompressed data with original */
86
2.29k
    if (size > 0 && nchunks > 0) {
87
2.29k
      if (dsize < 0 || memcmp(data, uncompressed_data, size) != 0) {
88
416
        printf("Decompression data does not match original %d\n", dsize);
89
416
      }
90
2.29k
    }
91
92
2.29k
    free(uncompressed_data);
93
2.29k
  }
94
95
  /* Free resources */
96
2.29k
  blosc2_schunk_free(schunk);
97
98
2.29k
  blosc2_destroy();
99
2.29k
  return 0;
100
2.29k
}
101
102
#ifdef __cplusplus
103
}
104
#endif