summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Davenport <qball@gmpclient.org>2020-10-17 21:59:12 +0200
committerDave Davenport <qball@gmpclient.org>2020-10-17 21:59:12 +0200
commitcc5a1989d867078a384b0904592ce718f90829dd (patch)
treeec73f9b646791edbce9e64dd3b5b7896aee559b0
parente00ef7d99365ed400be1d6957666e15d510d73ea (diff)
[RofiIconFetcher] Don't exit out on libjpeg error, but don't load image.
-rw-r--r--configure.ac1
-rw-r--r--source/rofi-icon-fetcher.c33
2 files changed, 32 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac
index 2adc8c53..f05ee356 100644
--- a/configure.ac
+++ b/configure.ac
@@ -126,6 +126,7 @@ AC_SEARCH_LIBS([floor],[m],, AC_MSG_ERROR("Could not find floor in math lib
AC_SEARCH_LIBS([ceil], [m],, AC_MSG_ERROR("Could not find ceil in math library"))
AC_CHECK_HEADER([sysexits.h],, AC_MSG_ERROR("Could not find the sysexists.h header file"))
+AC_CHECK_HEADER([setjmp.h],, AC_MSG_ERROR("Could not find the setjmp.h header file"))
dnl ---------------------------------------------------------------------
dnl Check dependencies
diff --git a/source/rofi-icon-fetcher.c b/source/rofi-icon-fetcher.c
index 09f9d8e6..60ede6f3 100644
--- a/source/rofi-icon-fetcher.c
+++ b/source/rofi-icon-fetcher.c
@@ -42,6 +42,8 @@
#include <stdint.h>
#include <jpeglib.h>
+#include <setjmp.h>
+
typedef struct
{
// Context for icon-themes.
@@ -171,11 +173,29 @@ static cairo_surface_t* cairo_image_surface_create_from_jpeg_private ( struct jp
return surface;
}
+struct jpegErrorManager {
+ /* "public" fields */
+ struct jpeg_error_mgr pub;
+ /* for return to caller */
+ jmp_buf setjmp_buffer;
+};
+char jpegLastErrorMsg[JMSG_LENGTH_MAX];
+static void jpegErrorExit (j_common_ptr cinfo)
+{
+ /* cinfo->err actually points to a jpegErrorManager struct */
+ struct jpegErrorManager* myerr = (struct jpegErrorManager*) cinfo->err;
+
+ /* Create the message */
+ ( *(cinfo->err->format_message) ) (cinfo, jpegLastErrorMsg);
+ g_warning ( jpegLastErrorMsg );
+
+ /* Jump to the setjmp point */
+ longjmp(myerr->setjmp_buffer, 1);
+}
static cairo_surface_t* cairo_image_surface_create_from_jpeg ( const char* file )
{
struct jpeg_decompress_struct cinfo;
- struct jpeg_error_mgr jerr;
cairo_surface_t * surface;
FILE * infile;
@@ -183,7 +203,16 @@ static cairo_surface_t* cairo_image_surface_create_from_jpeg ( const char* file
return NULL;
}
- cinfo.err = jpeg_std_error ( &jerr );
+ struct jpegErrorManager jerr;
+ cinfo.err = jpeg_std_error( &jerr.pub);
+ jerr.pub.error_exit = jpegErrorExit;
+ /* Establish the setjmp return context for my_error_exit to use. */
+ if (setjmp(jerr.setjmp_buffer)) {
+ /* If we get here, the JPEG code has signaled an error. */
+ jpeg_destroy_decompress(&cinfo);
+ fclose(infile);
+ return NULL;
+ }
jpeg_create_decompress ( &cinfo );
jpeg_stdio_src ( &cinfo, infile );