1 #ifdef __cplusplus
2 extern "C" {
3 #endif
4
5 #include <fcntl.h>
6 #include <setjmp.h>
7 #include <stdint.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <sys/stat.h>
11 #include <sys/types.h>
12 #include <unistd.h>
13
14 #include <libhfuzz/libhfuzz.h>
15
16 #include "cderror.h"
17 #include "jpeglib.h"
18
19 struct jpeg_decompress_struct cinfo;
20 int null_fd = -1;
21
22 struct jpegErrorManager {
23 struct jpeg_error_mgr pub;
24 jmp_buf setjmp_buffer;
25 };
26
27 struct jpegErrorManager jerr;
28
jpegErrorExit(j_common_ptr cinfo)29 void jpegErrorExit(j_common_ptr cinfo)
30 {
31 struct jpegErrorManager* myerr = (struct jpegErrorManager*)cinfo->err;
32 longjmp(myerr->setjmp_buffer, 1);
33 }
34
35 static const char* const cdjpeg_message_table[] = {
36 #include "cderror.h"
37 NULL
38 };
39
LLVMFuzzerInitialize(int * argc,char *** argv)40 int LLVMFuzzerInitialize(int* argc, char*** argv)
41 {
42 null_fd = open("/dev/null", O_WRONLY);
43
44 cinfo.err = jpeg_std_error(&jerr.pub);
45 jerr.pub.error_exit = jpegErrorExit;
46
47 jerr.pub.addon_message_table = cdjpeg_message_table;
48 jerr.pub.first_addon_message = JMSG_FIRSTADDONCODE;
49 jerr.pub.last_addon_message = JMSG_LASTADDONCODE;
50
51 jpeg_create_decompress(&cinfo);
52 return 0;
53 }
54
LLVMFuzzerTestOneInput(const uint8_t * buf,size_t len)55 int LLVMFuzzerTestOneInput(const uint8_t* buf, size_t len)
56 {
57 if (setjmp(jerr.setjmp_buffer)) {
58 goto out;
59 }
60
61 jpeg_mem_src(&cinfo, buf, len);
62
63 if (jpeg_read_header(&cinfo, TRUE) != JPEG_HEADER_OK) {
64 goto out;
65 }
66
67 if (cinfo.output_height > 10000 || cinfo.output_width > 10000) {
68 goto out;
69 }
70
71 cinfo.mem->max_memory_to_use = (1024 * 1024 * 1024);
72 cinfo.mem->max_alloc_chunk = (1024 * 128 * 256);
73
74 jpeg_start_decompress(&cinfo);
75
76 int row_stride = cinfo.output_width * cinfo.output_components;
77 JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1);
78 while (cinfo.output_scanline < cinfo.output_height) {
79 #if defined(__clang__)
80 #if __has_feature(memory_sanitizer)
81 __msan_poison(buffer[0], row_stride);
82 #endif /* __has_feature(memory_sanitizer) */
83 #endif /* defined(__clang__) */
84 jpeg_read_scanlines(&cinfo, buffer, 1);
85 write(null_fd, buffer[0], row_stride);
86 }
87
88 out:
89 jpeg_abort_decompress(&cinfo);
90 return 0;
91 }
92
93 #ifdef __cplusplus
94 }
95 #endif
96