blob: 499522425c409b60730978738cdf69ebe5f53567 [file] [log] [blame]
#ifdef __cplusplus
extern "C" {
#endif
#include <fcntl.h>
#include <setjmp.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <libhfuzz/libhfuzz.h>
#include "cderror.h"
#include "jpeglib.h"
struct jpeg_decompress_struct cinfo;
int null_fd = -1;
struct jpegErrorManager {
struct jpeg_error_mgr pub;
jmp_buf setjmp_buffer;
};
struct jpegErrorManager jerr;
void jpegErrorExit(j_common_ptr cinfo)
{
struct jpegErrorManager* myerr = (struct jpegErrorManager*)cinfo->err;
longjmp(myerr->setjmp_buffer, 1);
}
static const char* const cdjpeg_message_table[] = {
#include "cderror.h"
NULL
};
int LLVMFuzzerInitialize(int* argc, char*** argv)
{
null_fd = open("/dev/null", O_WRONLY);
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = jpegErrorExit;
jerr.pub.addon_message_table = cdjpeg_message_table;
jerr.pub.first_addon_message = JMSG_FIRSTADDONCODE;
jerr.pub.last_addon_message = JMSG_LASTADDONCODE;
jpeg_create_decompress(&cinfo);
return 0;
}
int LLVMFuzzerTestOneInput(const uint8_t* buf, size_t len)
{
if (setjmp(jerr.setjmp_buffer)) {
goto out;
}
jpeg_mem_src(&cinfo, buf, len);
if (jpeg_read_header(&cinfo, TRUE) != JPEG_HEADER_OK) {
goto out;
}
if (cinfo.output_height > 10000 || cinfo.output_width > 10000) {
goto out;
}
cinfo.mem->max_memory_to_use = (1024 * 1024 * 1024);
cinfo.mem->max_alloc_chunk = (1024 * 128 * 256);
jpeg_start_decompress(&cinfo);
int row_stride = cinfo.output_width * cinfo.output_components;
JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1);
while (cinfo.output_scanline < cinfo.output_height) {
#if defined(__clang__)
#if __has_feature(memory_sanitizer)
__msan_poison(buffer[0], row_stride);
#endif /* __has_feature(memory_sanitizer) */
#endif /* defined(__clang__) */
jpeg_read_scanlines(&cinfo, buffer, 1);
write(null_fd, buffer[0], row_stride);
}
out:
jpeg_abort_decompress(&cinfo);
return 0;
}
#ifdef __cplusplus
}
#endif