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 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 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 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