mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-09 23:34:20 +00:00
PNGImageFormat: Avoid crashing when attempting to write an invalid image
The default error handler could cause crashes, so we now set up a custom error handler both when reading and writing PNGs. The HeapBlock and BitmapData automatic variables have moved, so that their destructors will still run as expected in the failure case. Note that it's UB to call longjmp to unwind the stack to the previous setjmp, if said unwinding would normally cause non-trivial destructors to run.
This commit is contained in:
parent
51c4a484ee
commit
e0faa5c255
1 changed files with 24 additions and 12 deletions
|
|
@ -332,14 +332,6 @@ namespace PNGHelpers
|
|||
static_cast<OutputStream*> (png_get_io_ptr (png))->write (data, length);
|
||||
}
|
||||
|
||||
#if ! JUCE_USING_COREIMAGE_LOADER
|
||||
static void JUCE_CDECL readCallback (png_structp png, png_bytep data, png_size_t length)
|
||||
{
|
||||
static_cast<InputStream*> (png_get_io_ptr (png))->read (data, (int) length);
|
||||
}
|
||||
|
||||
struct PNGErrorStruct {};
|
||||
|
||||
static void JUCE_CDECL errorCallback (png_structp p, png_const_charp)
|
||||
{
|
||||
#ifdef PNG_SETJMP_SUPPORTED
|
||||
|
|
@ -351,6 +343,14 @@ namespace PNGHelpers
|
|||
|
||||
static void JUCE_CDECL warningCallback (png_structp, png_const_charp) {}
|
||||
|
||||
#if ! JUCE_USING_COREIMAGE_LOADER
|
||||
static void JUCE_CDECL readCallback (png_structp png, png_bytep data, png_size_t length)
|
||||
{
|
||||
static_cast<InputStream*> (png_get_io_ptr (png))->read (data, (int) length);
|
||||
}
|
||||
|
||||
struct PNGErrorStruct {};
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4611)
|
||||
|
||||
static bool readHeader (InputStream& in, png_structp pngReadStruct, png_infop pngInfoStruct, jmp_buf& errorJumpBuf,
|
||||
|
|
@ -528,15 +528,31 @@ Image PNGImageFormat::decodeImage (InputStream& in)
|
|||
|
||||
bool PNGImageFormat::writeImageToStream (const Image& image, OutputStream& out)
|
||||
{
|
||||
if (! image.isValid())
|
||||
return false;
|
||||
|
||||
using namespace pnglibNamespace;
|
||||
auto width = image.getWidth();
|
||||
auto height = image.getHeight();
|
||||
|
||||
HeapBlock<uint8> rowData (width * 4);
|
||||
const Image::BitmapData srcData (image, Image::BitmapData::readOnly);
|
||||
|
||||
auto pngWriteStruct = png_create_write_struct (PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
|
||||
|
||||
if (pngWriteStruct == nullptr)
|
||||
return false;
|
||||
|
||||
jmp_buf errorJumpBuf;
|
||||
png_set_error_fn (pngWriteStruct, &errorJumpBuf, PNGHelpers::errorCallback, PNGHelpers::warningCallback);
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4611)
|
||||
|
||||
if (setjmp (errorJumpBuf) != 0)
|
||||
return false;
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_MSVC
|
||||
|
||||
auto pngInfoStruct = png_create_info_struct (pngWriteStruct);
|
||||
|
||||
if (pngInfoStruct == nullptr)
|
||||
|
|
@ -554,8 +570,6 @@ bool PNGImageFormat::writeImageToStream (const Image& image, OutputStream& out)
|
|||
PNG_COMPRESSION_TYPE_BASE,
|
||||
PNG_FILTER_TYPE_BASE);
|
||||
|
||||
HeapBlock<uint8> rowData (width * 4);
|
||||
|
||||
png_color_8 sig_bit;
|
||||
sig_bit.red = 8;
|
||||
sig_bit.green = 8;
|
||||
|
|
@ -569,8 +583,6 @@ bool PNGImageFormat::writeImageToStream (const Image& image, OutputStream& out)
|
|||
png_set_shift (pngWriteStruct, &sig_bit);
|
||||
png_set_packing (pngWriteStruct);
|
||||
|
||||
const Image::BitmapData srcData (image, Image::BitmapData::readOnly);
|
||||
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
uint8* dst = rowData;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue