Hi Jules,
juce_loadJPEGImageFromStream currently ignores all jpeg decoding errors silentlty.
This is very problematic in our code, which can be told to decode jpeg images on possibly very, very bad input streams (read: mp3 picture frames ).
When this happens, the jpglib routines continue execution on a very corrupted internal state (read: null pointers )
Furthermore, from what I read in the full jpglib source and usage examples, it seems like ERREXIT should not be silently ignored and c client code should use setjmp/longjmp handlers to resume execution in user code. For us C++ folks, this amounts to exception throwing and handling.
The following code is a rather simple fix that does just that.
It also contains a check that skips decoding of zero-sized images.
--- juce_JPEGLoaderBug/juce_JPEGLoader.cpp Wed Oct 10 10:41:32 2007
+++ juce_JPEGLoaderBug/juce_JPEGLoader.patched.cpp Mon Oct 29 18:09:45 2007
@@ -54,6 +54,20 @@
//==============================================================================
+
+struct JPEGDecodingFailure {};
+
+void fatalErrorHandler (j_common_ptr cinfo)
+{
+ char errorBuffer [JMSG_LENGTH_MAX];
+ (*cinfo->err->format_message)(cinfo, errorBuffer);
+ jpeg_destroy(cinfo);
+
+ Logger::outputDebugString(String("JPEG decoding error: ") << errorBuffer);
+
+ throw JPEGDecodingFailure();
+}
+
static void silentErrorCallback1 (j_common_ptr)
{
}
@@ -70,7 +84,7 @@
{
zerostruct (err);
- err.error_exit = silentErrorCallback1;
+ err.error_exit = fatalErrorHandler;
err.emit_message = silentErrorCallback2;
err.output_message = silentErrorCallback1;
err.format_message = silentErrorCallback3;
@@ -124,12 +138,22 @@
jpegDecompStruct.src->next_input_byte = (const unsigned char*) mb.getData();
jpegDecompStruct.src->bytes_in_buffer = mb.getSize();
+ try
+ {
jpeg_read_header (&jpegDecompStruct, TRUE);
+ }
+ catch (JPEGDecodingFailure&)
+ {
+ return image;
+ }
jpeg_calc_output_dimensions (&jpegDecompStruct);
const int width = jpegDecompStruct.output_width;
const int height = jpegDecompStruct.output_height;
+
+ if (width * height == 0)
+ return image;
jpegDecompStruct.out_color_space = JCS_RGB;
Would it be a problem to commit something along those lines to the trunk?
Thanks.