oss-fuzz/projects/jbig2dec/jbig2_fuzzer.cc

151 lines
3.5 KiB
C++

/*
# Copyright 2018 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################
*/
#include <cstdint>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "jbig2.h"
#define ALIGNMENT 16
#define MBYTE (1024 * 1024)
#define GBYTE (1024 * MBYTE)
#define MAX_ALLOCATION (1 * GBYTE)
static uint64_t total = 0;
static uint64_t peak = 0;
static void *jbig2_alloc(Jbig2Allocator *allocator, size_t size)
{
void *ptr;
if (size == 0)
return NULL;
if (size > MAX_ALLOCATION - ALIGNMENT - total)
return NULL;
ptr = malloc(size + ALIGNMENT);
if (ptr == NULL)
return NULL;
memcpy(ptr, &size, sizeof(size));
total += size + ALIGNMENT;
if (peak == 0 || total / MBYTE > peak / MBYTE) {
peak = total;
fprintf(stderr, "memory: limit: %u Mbyte peak usage: %u Mbyte\n", MAX_ALLOCATION, peak);
}
return (unsigned char *) ptr + ALIGNMENT;
}
static void jbig2_free(Jbig2Allocator *allocator, void *p)
{
int size;
if (p == NULL)
return;
memcpy(&size, (unsigned char *) p - ALIGNMENT, sizeof(size));
total -= size + ALIGNMENT;
free((unsigned char *) p - ALIGNMENT);
}
static void *jbig2_realloc(Jbig2Allocator *allocator, void *p, size_t size)
{
unsigned char *oldp = p ? (unsigned char *) p - ALIGNMENT : NULL;
if (size > SIZE_MAX - ALIGNMENT)
return NULL;
if (oldp == NULL)
{
if (size == 0)
return NULL;
if (size > MAX_ALLOCATION - ALIGNMENT - total)
return NULL;
p = malloc(size + ALIGNMENT);
if (p == NULL)
return NULL;
}
else
{
int oldsize;
memcpy(&oldsize, oldp, sizeof(oldsize));
if (size == 0)
{
total -= oldsize + ALIGNMENT;
free(oldp);
return NULL;
}
if (size > MAX_ALLOCATION - total + oldsize)
return NULL;
p = realloc(oldp, size + ALIGNMENT);
if (p == NULL)
return NULL;
total -= oldsize + ALIGNMENT;
}
memcpy(p, &size, sizeof(size));
total += size + ALIGNMENT;
if (peak == 0 || total / MBYTE > peak / MBYTE) {
peak = total;
fprintf(stderr, "memory: limit: %u Mbyte peak usage: %u Mbyte\n", MAX_ALLOCATION, peak);
}
return (unsigned char *) p + ALIGNMENT;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
Jbig2Allocator allocator;
Jbig2Ctx *ctx = NULL;
allocator.alloc = jbig2_alloc;
allocator.free = jbig2_free;
allocator.realloc = jbig2_realloc;
ctx = jbig2_ctx_new(&allocator, (Jbig2Options) 0, NULL, NULL, NULL);
if (jbig2_data_in(ctx, data, size) == 0)
{
if (jbig2_complete_page(ctx) == 0)
{
Jbig2Image *image = jbig2_page_out(ctx);
if (image != NULL)
{
int sum = 0;
for (int i = 0; i < image->height * image->stride; i++)
sum += image->data[i];
printf("sum of image data bytes: %d\n", sum);
}
jbig2_release_page(ctx, image);
}
}
jbig2_ctx_free(ctx);
fprintf(stderr, "memory: limit: %u Mbyte peak usage: %u Mbyte\n", MAX_ALLOCATION, peak);
return 0;
}