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;
|
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)
|
int ImageIO::loadJPEGFromMemory (const char* buffer, int bufsize)
|
||||||
{
|
{
|
||||||
jpeg_decompress_struct cinfo;
|
jpeg_decompress_struct cinfo;
|
||||||
jpeg_error_mgr jerr;
|
|
||||||
cinfo.err = my_jpeg_std_error(&jerr);
|
|
||||||
jpeg_create_decompress(&cinfo);
|
jpeg_create_decompress(&cinfo);
|
||||||
|
|
||||||
jpeg_memory_src (&cinfo,(const JOCTET*)buffer,bufsize);
|
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) {
|
if (pl) {
|
||||||
pl->setProgressStr ("PROGRESSBAR_LOADJPEG");
|
pl->setProgressStr ("PROGRESSBAR_LOADJPEG");
|
||||||
pl->setProgress (0.0);
|
pl->setProgress (0.0);
|
||||||
@@ -356,7 +396,6 @@ int ImageIO::loadJPEGFromMemory (const char* buffer, int bufsize)
|
|||||||
|
|
||||||
setup_read_icc_profile (&cinfo);
|
setup_read_icc_profile (&cinfo);
|
||||||
|
|
||||||
//jpeg_memory_src (&cinfo,buffer,bufsize);
|
|
||||||
jpeg_read_header(&cinfo, TRUE);
|
jpeg_read_header(&cinfo, TRUE);
|
||||||
|
|
||||||
deleteLoadedProfileData();
|
deleteLoadedProfileData();
|
||||||
@@ -396,11 +435,6 @@ int ImageIO::loadJPEGFromMemory (const char* buffer, int bufsize)
|
|||||||
pl->setProgress (1.0);
|
pl->setProgress (1.0);
|
||||||
}
|
}
|
||||||
return IMIO_SUCCESS;
|
return IMIO_SUCCESS;
|
||||||
}
|
|
||||||
else {
|
|
||||||
jpeg_destroy_decompress(&cinfo);
|
|
||||||
return IMIO_READERROR;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ImageIO::loadJPEG (Glib::ustring fname) {
|
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
|
// Quality 0..100, subsampling: 1=low quality, 2=medium, 3=high
|
||||||
int ImageIO::saveJPEG (Glib::ustring fname, int quality, int subSamp) {
|
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()));
|
const char* data((const char*)fdata(ri->get_thumbOffset(),ri->get_file()));
|
||||||
if ( (unsigned char)data[1] == 0xd8 )
|
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());
|
err = img->loadJPEGFromMemory(data,ri->get_thumbLength());
|
||||||
#else
|
|
||||||
err = img->loadJPEGFromMemory(data,ri->get_thumbLength());
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user