Coverage Report

Created: 2025-12-19 06:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/jbig2_fuzzer.cc
Line
Count
Source
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 <cstdint>
20
#include <stdlib.h>
21
#include <string.h>
22
#include <stdio.h>
23
24
#include "jbig2.h"
25
26
456M
#define ALIGNMENT ((size_t) 16)
27
57.0M
#define KBYTE ((size_t) 1024)
28
57.0M
#define MBYTE (1024 * KBYTE)
29
#define GBYTE (1024 * MBYTE)
30
57.0M
#define MAX_ALLOCATION (32 * MBYTE)
31
32
static size_t used;
33
34
static void *jbig2_fuzzer_reached_limit(size_t oldsize, size_t size)
35
1.79k
{
36
1.79k
  if (oldsize == 0)
37
1.72k
    fprintf(stderr, "limit: %zu Mbyte used: %zu Mbyte allocation: %zu: limit reached\n", MAX_ALLOCATION / MBYTE, used / MBYTE, size);
38
66
  else
39
66
    fprintf(stderr, "limit: %zu Mbyte used: %zu Mbyte reallocation: %zu -> %zu: limit reached\n", MAX_ALLOCATION / MBYTE, used / MBYTE, oldsize, size);
40
1.79k
  fflush(0);
41
1.79k
  return NULL;
42
1.79k
}
43
44
static void *jbig2_fuzzer_alloc(Jbig2Allocator *allocator, size_t size)
45
57.0M
{
46
57.0M
  char *ptr = NULL;
47
48
57.0M
  if (size == 0)
49
5.95k
    return NULL;
50
57.0M
  if (size > SIZE_MAX - ALIGNMENT)
51
0
    return NULL;
52
57.0M
  if (size + ALIGNMENT > MAX_ALLOCATION - used)
53
1.72k
    return jbig2_fuzzer_reached_limit(0, size + ALIGNMENT);
54
55
57.0M
  ptr = (char *) malloc(size + ALIGNMENT);
56
57.0M
  if (ptr == NULL)
57
0
    return NULL;
58
59
57.0M
  memcpy(ptr, &size, sizeof(size));
60
57.0M
  used += size + ALIGNMENT;
61
62
57.0M
  return ptr + ALIGNMENT;
63
57.0M
}
64
65
static void jbig2_fuzzer_free(Jbig2Allocator *allocator, void *ptr)
66
57.1M
{
67
57.1M
  size_t size;
68
69
57.1M
  if (ptr == NULL)
70
105k
    return;
71
57.0M
  if (ptr < (void *) ALIGNMENT)
72
0
    return;
73
74
57.0M
  ptr = (char *) ptr - ALIGNMENT;
75
57.0M
  memcpy(&size, ptr, sizeof(size));
76
77
57.0M
  used -= size + ALIGNMENT;
78
57.0M
  free(ptr);
79
57.0M
}
80
81
static void *jbig2_fuzzer_realloc(Jbig2Allocator *allocator, void *old, size_t size)
82
4.88k
{
83
4.88k
  size_t oldsize;
84
4.88k
  char *ptr;
85
86
4.88k
  if (old == NULL)
87
0
    return jbig2_fuzzer_alloc(allocator, size);
88
4.88k
  if (old < (void *) ALIGNMENT)
89
0
    return NULL;
90
91
4.88k
  if (size == 0) {
92
0
    jbig2_fuzzer_free(allocator, old);
93
0
    return NULL;
94
0
  }
95
4.88k
  if (size > SIZE_MAX - ALIGNMENT)
96
0
    return NULL;
97
98
4.88k
  old = (char *) old - ALIGNMENT;
99
4.88k
  memcpy(&oldsize, old, sizeof(oldsize));
100
101
4.88k
  if (size + ALIGNMENT > MAX_ALLOCATION - used + oldsize + ALIGNMENT)
102
66
    return jbig2_fuzzer_reached_limit(oldsize + ALIGNMENT, size + ALIGNMENT);
103
104
4.82k
  ptr = (char *) realloc(old, size + ALIGNMENT);
105
4.82k
  if (ptr == NULL)
106
0
    return NULL;
107
108
4.82k
  used -= oldsize + ALIGNMENT;
109
4.82k
  memcpy(ptr, &size, sizeof(size));
110
4.82k
  used += size + ALIGNMENT;
111
112
4.82k
  return ptr + ALIGNMENT;
113
4.82k
}
114
115
7.35k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
116
7.35k
  Jbig2Allocator allocator;
117
7.35k
  Jbig2Ctx *ctx = NULL;
118
119
7.35k
  used = 0;
120
121
7.35k
  allocator.alloc = jbig2_fuzzer_alloc;
122
7.35k
  allocator.free = jbig2_fuzzer_free;
123
7.35k
  allocator.realloc = jbig2_fuzzer_realloc;
124
125
7.35k
  ctx = jbig2_ctx_new(&allocator, (Jbig2Options) 0, NULL, NULL, NULL);
126
7.35k
  if (jbig2_data_in(ctx, data, size) == 0)
127
6.21k
  {
128
6.21k
    if (jbig2_complete_page(ctx) == 0)
129
622
    {
130
622
      Jbig2Image *image = jbig2_page_out(ctx);
131
622
      if (image != NULL)
132
622
      {
133
622
        int sum = 0;
134
1.00G
        for (int i = 0; i < image->height * image->stride; i++)
135
1.00G
          sum += image->data[i];
136
622
        printf("sum of image data bytes: %d\n", sum);
137
622
      }
138
622
      jbig2_release_page(ctx, image);
139
622
    }
140
6.21k
  }
141
7.35k
  jbig2_ctx_free(ctx);
142
143
7.35k
  return 0;
144
7.35k
}