summaryrefslogtreecommitdiff
path: root/fitz
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2012-12-03 13:14:18 +0000
committerRobin Watts <robin.watts@artifex.com>2012-12-03 16:28:52 +0000
commitf6b64c3e6e3c91f71c4febe35037a1cb57fe5461 (patch)
tree52c7c7407156d03ba06f7b86b21854da6e5d5a18 /fitz
parent62320204bf806686dd07d27d8110670914a874ca (diff)
downloadmupdf-f6b64c3e6e3c91f71c4febe35037a1cb57fe5461.tar.xz
Fix potential infinite loop in jpeg error handling code.
Turns out that jpeg_finish_decompress can throw errors, hence can cause an infinite loop. This is fixed here by changing the jpeg error code to be fz_throw based. Thanks to zeniko for this patch. This highlights something that I hadn't fully appreciated before; anything that throws in a fz_always region will reenter that region. I think I have a way to fix this so that any throws in the fz_always region go immediately to the fz_catch.
Diffstat (limited to 'fitz')
-rw-r--r--fitz/image_jpeg.c34
1 files changed, 16 insertions, 18 deletions
diff --git a/fitz/image_jpeg.c b/fitz/image_jpeg.c
index aedd48c8..925ecbfb 100644
--- a/fitz/image_jpeg.c
+++ b/fitz/image_jpeg.c
@@ -3,18 +3,13 @@
#include <jpeglib.h>
#include <setjmp.h>
-struct jpeg_error_mgr_jmp
+static void error_exit(j_common_ptr cinfo)
{
- struct jpeg_error_mgr super;
- jmp_buf env;
char msg[JMSG_LENGTH_MAX];
-};
+ fz_context *ctx = (fz_context *)cinfo->client_data;
-static void error_exit(j_common_ptr cinfo)
-{
- struct jpeg_error_mgr_jmp *err = (struct jpeg_error_mgr_jmp *)cinfo->err;
- cinfo->err->format_message(cinfo, err->msg);
- longjmp(err->env, 1);
+ cinfo->err->format_message(cinfo, msg);
+ fz_throw(ctx, "jpeg error: %s", msg);
}
static void init_source(j_decompress_ptr cinfo)
@@ -53,7 +48,7 @@ fz_pixmap *
fz_load_jpeg(fz_context *ctx, unsigned char *rbuf, int rlen)
{
struct jpeg_decompress_struct cinfo;
- struct jpeg_error_mgr_jmp err;
+ struct jpeg_error_mgr err;
struct jpeg_source_mgr src;
unsigned char *row[1], *sp, *dp;
fz_colorspace *colorspace;
@@ -68,13 +63,8 @@ fz_load_jpeg(fz_context *ctx, unsigned char *rbuf, int rlen)
fz_try(ctx)
{
- if (setjmp(err.env))
- {
- fz_throw(ctx, "jpeg error: %s", err.msg);
- }
-
- cinfo.err = jpeg_std_error(&err.super);
- err.super.error_exit = error_exit;
+ cinfo.err = jpeg_std_error(&err);
+ err.error_exit = error_exit;
jpeg_create_decompress(&cinfo);
@@ -136,7 +126,15 @@ fz_load_jpeg(fz_context *ctx, unsigned char *rbuf, int rlen)
{
fz_free(ctx, row[0]);
row[0] = NULL;
- jpeg_finish_decompress(&cinfo);
+ fz_try(ctx)
+ {
+ /* Annoyingly, jpeg_finish_decompress can throw */
+ jpeg_finish_decompress(&cinfo);
+ }
+ fz_catch(ctx)
+ {
+ /* Ignore any errors here */
+ }
jpeg_destroy_decompress(&cinfo);
}
fz_catch(ctx)