From 7857fa8f637fd5d7b1fcb721f15302270c024dfd Mon Sep 17 00:00:00 2001 From: Devaev Maxim Date: Wed, 17 Apr 2019 07:14:19 +0300 Subject: [PATCH] blank: handling libjpeg errors --- src/http/blank.c | 57 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/src/http/blank.c b/src/http/blank.c index a8d35b3..d4b10ed 100644 --- a/src/http/blank.c +++ b/src/http/blank.c @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -34,8 +35,16 @@ #include "blank.h" +struct _jpeg_error_manager_t { + struct jpeg_error_mgr mgr; // Default manager + jmp_buf jmp; +}; + + static struct blank_t *_blank_init_internal(); static struct blank_t *_blank_init_external(const char *path); +static int _jpeg_read_geometry(FILE *fp, unsigned *width, unsigned *height); +static void _jpeg_error_handler(j_common_ptr jpeg); struct blank_t *blank_init(const char *path) { @@ -78,8 +87,6 @@ static struct blank_t *_blank_init_internal() { static struct blank_t *_blank_init_external(const char *path) { FILE *fp = NULL; - struct jpeg_error_mgr jpeg_error; - struct jpeg_decompress_struct jpeg; struct blank_t *blank; A_CALLOC(blank, 1); @@ -89,16 +96,9 @@ static struct blank_t *_blank_init_external(const char *path) { goto error; } - jpeg_create_decompress(&jpeg); - jpeg.err = jpeg_std_error(&jpeg_error); - jpeg_stdio_src(&jpeg, fp); - jpeg_read_header(&jpeg, TRUE); - jpeg_start_decompress(&jpeg); - - blank->width = jpeg.output_width; - blank->height = jpeg.output_height; - - jpeg_destroy_decompress(&jpeg); + if (_jpeg_read_geometry(fp, &blank->width, &blank->height) < 0) { + goto error; + } if (fseek(fp, 0, SEEK_SET) < 0) { LOG_PERROR("Can't seek to begin of the blank placeholder"); @@ -138,3 +138,36 @@ static struct blank_t *_blank_init_external(const char *path) { return blank; } + +static int _jpeg_read_geometry(FILE *fp, unsigned *width, unsigned *height) { + struct jpeg_decompress_struct jpeg; + struct _jpeg_error_manager_t jpeg_error; + + jpeg_create_decompress(&jpeg); + + jpeg.err = jpeg_std_error((struct jpeg_error_mgr *)&jpeg_error); + jpeg_error.mgr.error_exit = _jpeg_error_handler; + if (setjmp(jpeg_error.jmp) < 0) { + jpeg_destroy_decompress(&jpeg); + return -1; + } + + jpeg_stdio_src(&jpeg, fp); + jpeg_read_header(&jpeg, TRUE); + jpeg_start_decompress(&jpeg); + + *width = jpeg.output_width; + *height = jpeg.output_height; + + jpeg_destroy_decompress(&jpeg); + return 0; +} + +static void _jpeg_error_handler(j_common_ptr jpeg) { + struct _jpeg_error_manager_t *jpeg_error = (struct _jpeg_error_manager_t *)jpeg->err; + char msg[JMSG_LENGTH_MAX]; + + (*jpeg_error->mgr.format_message)(jpeg, msg); + LOG_ERROR("Invalid blank placeholder: %s", msg); + longjmp(jpeg_error->jmp, -1); +}