Coverage Report

Created: 2024-05-21 06:11

/src/lzo_compress_target.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
# Copyright 2018 Google Inc.
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 <assert.h>
20
#include <stdbool.h>
21
#include <stdint.h>
22
#include <stdio.h>
23
#include <stdlib.h>
24
25
#include "lzo1x.h"
26
#include "lzoconf.h"
27
28
/* Work-memory needed for compression. Allocate memory in units
29
 * of 'lzo_align_t' (instead of 'char') to make sure it is properly aligned.
30
 */
31
#define HEAP_ALLOC(var, size) \
32
  lzo_align_t __LZO_MMODEL    \
33
      var[((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t)]
34
35
static HEAP_ALLOC(wrkmem, LZO1X_1_MEM_COMPRESS);
36
37
924
extern int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
38
924
  int r;
39
924
  lzo_uint compressed_len;
40
924
  lzo_uint decompressed_len;
41
42
  /* Since we allocate in/out on the stack,
43
   * we can't handle too large size.
44
   */
45
924
  if (size > (1 << 20)) {
46
0
    size = 1 << 20;
47
0
  }
48
49
  /* We want to compress the data block at 'in' with length 'IN_LEN' to
50
   * the block at 'out'. Because the input block may be incompressible,
51
   * we must provide a little more output space in case that compression
52
   * is not possible.
53
   */
54
924
  unsigned char* __LZO_MMODEL decompressed = malloc(size + 1);
55
924
  if (!decompressed) {
56
0
    return 0;
57
0
  }
58
924
  unsigned char* __LZO_MMODEL compressed = malloc(size + size / 16 + 64 + 3);
59
924
  if (!compressed) {
60
0
    free(decompressed);
61
0
    return 0;
62
0
  }
63
64
924
  static bool isInit = false;
65
924
  if (!isInit) {
66
1
    if (lzo_init() != LZO_E_OK) {
67
#ifdef __DEBUG__
68
      printf("internal error - lzo_init() failed !!!\n");
69
#endif
70
0
      free(compressed);
71
0
      free(decompressed);
72
0
      return 0;
73
0
    }
74
1
    isInit = true;
75
1
  }
76
77
  /* Compress with LZO1X-1. */
78
924
  r = lzo1x_1_compress(data, size, compressed, &compressed_len, wrkmem);
79
924
  assert(r == LZO_E_OK);
80
#ifdef __DEBUG__
81
  printf("compressed %lu bytes into %lu bytes\n", (unsigned long)size,
82
         (unsigned long)out_len);
83
#endif
84
85
  /* check for an incompressible block */
86
924
  if (compressed_len >= size) {
87
#ifdef __DEBUG__
88
    printf("This block contains incompressible data.\n");
89
#endif
90
384
    free(compressed);
91
384
    free(decompressed);
92
384
    return 0;
93
384
  }
94
95
  // Decompress; allow 1 extra byte of output to make sure decoder does not
96
  // produce unexpected output.
97
540
  decompressed_len = size + 1;
98
540
  r = lzo1x_decompress(compressed, compressed_len, decompressed,
99
540
                       &decompressed_len, /*wrkmem=*/NULL);
100
540
  assert(r == LZO_E_OK && decompressed_len == size);
101
#ifdef __DEBUG__
102
  printf("decompressed %lu bytes back into %lu bytes\n", (unsigned long)out_len,
103
         (unsigned long)size);
104
#endif
105
540
  free(compressed);
106
540
  free(decompressed);
107
540
  return 0;
108
540
}