mirror of https://github.com/PCSX2/pcsx2.git
Image: Fix crash loading corrupted/invalid JPEG files
Backport from: afea18f65e
This commit is contained in:
parent
fd5a652270
commit
9a50218400
|
@ -8,6 +8,7 @@
|
|||
#include "ScopedGuard.h"
|
||||
#include "StringUtil.h"
|
||||
|
||||
#include <common/FastJmp.h>
|
||||
#include <jpeglib.h>
|
||||
#include <png.h>
|
||||
#include <webp/decode.h>
|
||||
|
@ -383,39 +384,40 @@ namespace
|
|||
struct JPEGErrorHandler
|
||||
{
|
||||
jpeg_error_mgr err;
|
||||
jmp_buf jbuf;
|
||||
};
|
||||
} // namespace
|
||||
fastjmp_buf jbuf;
|
||||
|
||||
static bool HandleJPEGError(JPEGErrorHandler* eh)
|
||||
JPEGErrorHandler()
|
||||
{
|
||||
jpeg_std_error(&eh->err);
|
||||
jpeg_std_error(&err);
|
||||
err.error_exit = &ErrorExit;
|
||||
}
|
||||
|
||||
eh->err.error_exit = [](j_common_ptr cinfo) {
|
||||
static void ErrorExit(j_common_ptr cinfo)
|
||||
{
|
||||
JPEGErrorHandler* eh = (JPEGErrorHandler*)cinfo->err;
|
||||
char msg[JMSG_LENGTH_MAX];
|
||||
eh->err.format_message(cinfo, msg);
|
||||
Console.ErrorFmt("libjpeg fatal error: {}", msg);
|
||||
longjmp(eh->jbuf, 1);
|
||||
};
|
||||
|
||||
if (setjmp(eh->jbuf) == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
fastjmp_jmp(&eh->jbuf, 1);
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
template <typename T>
|
||||
static bool WrapJPEGDecompress(RGBA8Image* image, T setup_func)
|
||||
{
|
||||
std::vector<u8> scanline;
|
||||
jpeg_decompress_struct info = {};
|
||||
|
||||
JPEGErrorHandler err;
|
||||
if (!HandleJPEGError(&err))
|
||||
// NOTE: Be **very** careful not to allocate memory after calling this function.
|
||||
// It won't get freed, because fastjmp does not unwind the stack.
|
||||
JPEGErrorHandler errhandler;
|
||||
if (fastjmp_set(&errhandler.jbuf) != 0)
|
||||
{
|
||||
jpeg_destroy_decompress(&info);
|
||||
return false;
|
||||
|
||||
jpeg_decompress_struct info;
|
||||
info.err = &err.err;
|
||||
}
|
||||
info.err = &errhandler.err;
|
||||
jpeg_create_decompress(&info);
|
||||
setup_func(info);
|
||||
|
||||
|
@ -541,13 +543,17 @@ template <typename T>
|
|||
static bool WrapJPEGCompress(const RGBA8Image& image, u8 quality, T setup_func)
|
||||
{
|
||||
std::vector<u8> scanline;
|
||||
jpeg_compress_struct info = {};
|
||||
|
||||
JPEGErrorHandler err;
|
||||
if (!HandleJPEGError(&err))
|
||||
// NOTE: Be **very** careful not to allocate memory after calling this function.
|
||||
// It won't get freed, because fastjmp does not unwind the stack.
|
||||
JPEGErrorHandler errhandler;
|
||||
if (fastjmp_set(&errhandler.jbuf) != 0)
|
||||
{
|
||||
jpeg_destroy_compress(&info);
|
||||
return false;
|
||||
|
||||
jpeg_compress_struct info;
|
||||
info.err = &err.err;
|
||||
}
|
||||
info.err = &errhandler.err;
|
||||
jpeg_create_compress(&info);
|
||||
setup_func(info);
|
||||
|
||||
|
|
Loading…
Reference in New Issue