Crash on Win64 when embedded jpeg thumb is corrupted, Issue 2795
This commit is contained in:
@@ -338,16 +338,56 @@ int ImageIO::loadPNG (Glib::ustring fname) {
|
||||
return IMIO_SUCCESS;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_error_mgr pub; /* "public" fields */
|
||||
jmp_buf setjmp_buffer; /* for return to caller */
|
||||
} my_error_mgr;
|
||||
|
||||
void my_error_exit (j_common_ptr cinfo) {
|
||||
/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
|
||||
my_error_mgr *myerr = (my_error_mgr*) cinfo->err;
|
||||
/* Always display the message. */
|
||||
/* We could postpone this until after returning, if we chose. */
|
||||
(*cinfo->err->output_message) (cinfo);
|
||||
|
||||
/* Return control to the setjmp point */
|
||||
#if defined( WIN32 ) && defined( __x86_64__ )
|
||||
__builtin_longjmp(myerr->setjmp_buffer, 1);
|
||||
#else
|
||||
longjmp(myerr->setjmp_buffer, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int ImageIO::loadJPEGFromMemory (const char* buffer, int bufsize)
|
||||
{
|
||||
jpeg_decompress_struct cinfo;
|
||||
jpeg_error_mgr jerr;
|
||||
cinfo.err = my_jpeg_std_error(&jerr);
|
||||
jpeg_create_decompress(&cinfo);
|
||||
|
||||
jpeg_memory_src (&cinfo,(const JOCTET*)buffer,bufsize);
|
||||
if ( setjmp((reinterpret_cast<rt_jpeg_error_mgr*>(cinfo.src))->error_jmp_buf) == 0 )
|
||||
{
|
||||
|
||||
/* We use our private extension JPEG error handler.
|
||||
Note that this struct must live as long as the main JPEG parameter
|
||||
struct, to avoid dangling-pointer problems.
|
||||
*/
|
||||
my_error_mgr jerr;
|
||||
/* We set up the normal JPEG error routines, then override error_exit. */
|
||||
cinfo.err = jpeg_std_error(&jerr.pub);
|
||||
jerr.pub.error_exit = my_error_exit;
|
||||
|
||||
/* Establish the setjmp return context for my_error_exit to use. */
|
||||
#if defined( WIN32 ) && defined( __x86_64__ )
|
||||
if (__builtin_setjmp(jerr.setjmp_buffer)) {
|
||||
#else
|
||||
if (setjmp(jerr.setjmp_buffer)) {
|
||||
#endif
|
||||
/* If we get here, the JPEG code has signaled an error.
|
||||
We need to clean up the JPEG object and return.
|
||||
*/
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
return IMIO_READERROR;
|
||||
}
|
||||
|
||||
|
||||
if (pl) {
|
||||
pl->setProgressStr ("PROGRESSBAR_LOADJPEG");
|
||||
pl->setProgress (0.0);
|
||||
@@ -356,7 +396,6 @@ int ImageIO::loadJPEGFromMemory (const char* buffer, int bufsize)
|
||||
|
||||
setup_read_icc_profile (&cinfo);
|
||||
|
||||
//jpeg_memory_src (&cinfo,buffer,bufsize);
|
||||
jpeg_read_header(&cinfo, TRUE);
|
||||
|
||||
deleteLoadedProfileData();
|
||||
@@ -396,11 +435,6 @@ int ImageIO::loadJPEGFromMemory (const char* buffer, int bufsize)
|
||||
pl->setProgress (1.0);
|
||||
}
|
||||
return IMIO_SUCCESS;
|
||||
}
|
||||
else {
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
return IMIO_READERROR;
|
||||
}
|
||||
}
|
||||
|
||||
int ImageIO::loadJPEG (Glib::ustring fname) {
|
||||
@@ -836,25 +870,6 @@ int ImageIO::savePNG (Glib::ustring fname, int compression, volatile int bps) {
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_error_mgr pub; /* "public" fields */
|
||||
jmp_buf setjmp_buffer; /* for return to caller */
|
||||
} my_error_mgr;
|
||||
|
||||
void my_error_exit (j_common_ptr cinfo) {
|
||||
/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
|
||||
my_error_mgr *myerr = (my_error_mgr*) cinfo->err;
|
||||
/* Always display the message. */
|
||||
/* We could postpone this until after returning, if we chose. */
|
||||
(*cinfo->err->output_message) (cinfo);
|
||||
|
||||
/* Return control to the setjmp point */
|
||||
#if defined( WIN32 ) && defined( __x86_64__ )
|
||||
__builtin_longjmp(myerr->setjmp_buffer, 1);
|
||||
#else
|
||||
longjmp(myerr->setjmp_buffer, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Quality 0..100, subsampling: 1=low quality, 2=medium, 3=high
|
||||
int ImageIO::saveJPEG (Glib::ustring fname, int quality, int subSamp) {
|
||||
|
@@ -183,16 +183,7 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL
|
||||
const char* data((const char*)fdata(ri->get_thumbOffset(),ri->get_file()));
|
||||
if ( (unsigned char)data[1] == 0xd8 )
|
||||
{
|
||||
#if defined( __WIN32__ ) && defined( __x86_64__ )
|
||||
// This is a hack for Issue 2425, because loadJPEGFromMemory crashes on Win64 when jpg marker is incorrect
|
||||
// (should be 0xff 0xd8, but is 0x02 0xd8 for mrw files)
|
||||
std::string suffix = fname.length() > 4 ? fname.substr(fname.length()-3) : "";
|
||||
for (int i = 0; i < suffix.length(); i++) suffix[i] = std::tolower(suffix[i]);
|
||||
if(suffix != "mrw" || (unsigned char)data[0] == 0xff)
|
||||
err = img->loadJPEGFromMemory(data,ri->get_thumbLength());
|
||||
#else
|
||||
err = img->loadJPEGFromMemory(data,ri->get_thumbLength());
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Reference in New Issue
Block a user