Skip to content

Commit

Permalink
JPEG: Handle errors when saving with libjpeg
Browse files Browse the repository at this point in the history
If we are going to use my_error_exit(), we must use setjmp() to set up
its jump buffer before we start to compress, similar to what already
happened in the loading code path. Otherwise, errors in libjpeg will
result in a crash when we do a nonlocal goto to an uninitialized pointer.

Resolves: #429
Signed-off-by: Simon McVittie <[email protected]>
  • Loading branch information
smcv committed Mar 11, 2024
1 parent 85bd5cf commit 6d53995
Showing 1 changed file with 13 additions and 1 deletion.
14 changes: 13 additions & 1 deletion src/IMG_jpg.c
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,7 @@ static int IMG_SaveJPG_RW_jpeglib(SDL_Surface *surface, SDL_RWops *dst, int qual
struct my_error_mgr jerr;
JSAMPROW row_pointer[1];
SDL_Surface* jpeg_surface = surface;
Sint64 start;

if (!IMG_Init(IMG_INIT_JPG)) {
return -1;
Expand All @@ -499,10 +500,21 @@ static int IMG_SaveJPG_RW_jpeglib(SDL_Surface *surface, SDL_RWops *dst, int qual
}
}

/* Create a decompression structure and load the JPEG header */
/* Create a compression structure and load the JPEG header */
cinfo.err = lib.jpeg_std_error(&jerr.errmgr);
jerr.errmgr.error_exit = my_error_exit;
jerr.errmgr.output_message = output_no_message;
start = SDL_RWtell(dst);

if(setjmp(jerr.escape)) {
/* If we get here, libjpeg found an error */
lib.jpeg_destroy_compress(&cinfo);
if (jpeg_surface != surface) {
SDL_FreeSurface(jpeg_surface);
}
SDL_RWseek(dst, start, RW_SEEK_SET);
return IMG_SetError("Error saving JPEG with libjpeg");
}

lib.jpeg_create_compress(&cinfo);
jpeg_SDL_RW_dest(&cinfo, dst);
Expand Down

0 comments on commit 6d53995

Please sign in to comment.