Add extended errorhandling in jpegturbo loader to fix a crash. 56/19456/1
authorxinyan.mei <xinyan.mei@samsung.com>
Wed, 9 Apr 2014 06:51:56 +0000 (15:51 +0900)
committerVictor Cebollada <v.cebollada@samsung.com>
Fri, 11 Apr 2014 14:45:51 +0000 (15:45 +0100)
[Issue#] N/A
[Problem] crash at jpeg_read_header
[Cause] error handle for jpeg decompress
[Solution]
Added extended error handle to destroy jpeg_decompress_struct
and use setjmp/longjmp to jump out of the JPEG decoder.

Change-Id: If9455c43d234c8b82e73161fcd0177c98f2102e5
Signed-off-by: Victor Cebollada <v.cebollada@samsung.com>
platform-abstractions/slp/resource-loader/loader-jpeg-turbo.cpp [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index be3d1eb..e3489bc
@@ -27,6 +27,7 @@
 #include <libexif/exif-data.h>
 #include <libexif/exif-loader.h>
 #include <libexif/exif-tag.h>
+#include <setjmp.h>
 
 namespace Dali
 {
@@ -89,10 +90,27 @@ namespace
     char gray;
   };
 
-  void JpegFatalErrorHandler( j_common_ptr cinfo )
+  /**
+   * @brief Error handling bookeeping for the JPEG Turbo library's
+   * setjmp/longjmp simulated exceptions.
+   */
+  struct JpegErrorState {
+    struct jpeg_error_mgr errorManager;
+    jmp_buf jumpBuffer;
+  };
+
+  /**
+   * @brief Called by the JPEG library when it hits an error.
+   * We jump out of the library so our loader code can return an error.
+   */
+  void  JpegErrorHandler ( j_common_ptr cinfo )
   {
-    // LibJpeg causes an assert if this happens but we do not want that.
-    DALI_LOG_ERROR( "libjpeg-turbo fatal error in JPEG decoding.\n");
+    DALI_LOG_ERROR( "JpegErrorHandler(): libjpeg-turbo fatal error in JPEG decoding.\n" );
+    /* cinfo->err really points to a JpegErrorState struct, so coerce pointer */
+    JpegErrorState * myerr = reinterpret_cast<JpegErrorState *>( cinfo->err );
+
+    /* Return control to the setjmp point */
+    longjmp( myerr->jumpBuffer, 1 );
   }
 
   void JpegOutputMessageHandler( j_common_ptr cinfo )
@@ -178,11 +196,19 @@ bool LoadJpegHeader( FILE *fp, unsigned int &width, unsigned int &height )
 {
   // using libjpeg API to avoid having to read the whole file in a buffer
   struct jpeg_decompress_struct cinfo;
-  struct jpeg_error_mgr jerr;
-  cinfo.err = jpeg_std_error( &jerr );
+  struct JpegErrorState jerr;
+  cinfo.err = jpeg_std_error( &jerr.errorManager );
+
+  jerr.errorManager.output_message = JpegOutputMessageHandler;
+  jerr.errorManager.error_exit = JpegErrorHandler;
 
-  jerr.output_message = JpegOutputMessageHandler;
-  jerr.error_exit = JpegFatalErrorHandler;
+  // On error exit from the JPEG lib, control will pass via JpegErrorHandler
+  // into this branch body for cleanup and error return:
+  if(setjmp(jerr.jumpBuffer))
+  {
+    jpeg_destroy_decompress(&cinfo);
+    return false;
+  }
 
   jpeg_create_decompress( &cinfo );