Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(732)

Unified Diff: src/images/SkImageDecoder_libpng.cpp

Issue 24449003: Make Jpeg decoding more fault resistant. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: final rebase Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/images/SkImageDecoder_libjpeg.cpp ('k') | tests/JpegTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/images/SkImageDecoder_libpng.cpp
diff --git a/src/images/SkImageDecoder_libpng.cpp b/src/images/SkImageDecoder_libpng.cpp
index d3b45c3847488f013d3746fdd12ecac6e9500b25..4e4106aede85f8266c3b9ffd234e025f9f6a0e02 100644
--- a/src/images/SkImageDecoder_libpng.cpp
+++ b/src/images/SkImageDecoder_libpng.cpp
@@ -19,6 +19,10 @@
#include "SkUtils.h"
#include "transform_scanline.h"
+#if defined(SK_DEBUG)
+#include "SkRTConf.h" // SK_CONF_DECLARE
+#endif // defined(SK_DEBUG)
+
extern "C" {
#include "png.h"
}
@@ -40,6 +44,13 @@ extern "C" {
#define png_flush_ptr_NULL NULL
#endif
+#if defined(SK_DEBUG)
+SK_CONF_DECLARE(bool, c_suppressPNGImageDecoderWarnings,
+ "images.png.suppressDecoderWarnings", false,
+ "Suppress most PNG warnings when calling image decode functions.");
+#endif // defined(SK_DEBUG)
+
+
class SkPNGImageIndex {
public:
SkPNGImageIndex(SkStreamRewindable* stream, png_structp png_ptr, png_infop info_ptr)
@@ -199,6 +210,10 @@ static bool hasTransparencyInPalette(png_structp png_ptr, png_infop info_ptr) {
return false;
}
+void do_nothing_warning_fn(png_structp, png_const_charp) {
+ /* do nothing */
+}
+
bool SkPNGImageDecoder::onDecodeInit(SkStream* sk_stream, png_structp *png_ptrp,
png_infop *info_ptrp) {
/* Create and initialize the png_struct with the desired error handler
@@ -206,12 +221,27 @@ bool SkPNGImageDecoder::onDecodeInit(SkStream* sk_stream, png_structp *png_ptrp,
* you can supply NULL for the last three parameters. We also supply the
* the compiler header file version, so that we know if the application
* was compiled with a compatible version of the library. */
+
+#if defined(SK_DEBUG)
+ png_error_ptr user_warning_fn =
+ (c_suppressPNGImageDecoderWarnings) ? (&do_nothing_warning_fn) : NULL;
+ /* NULL means to leave as default library behavior. */
+ /* c_suppressPNGImageDecoderWarnings defaults to false. */
+ /* To suppress warnings with a SK_DEBUG binary, set the
+ * environment variable "skia_images_png_suppressDecoderWarnings"
+ * to "true". Inside a program that links to skia:
+ * SK_CONF_SET("images.png.suppressDecoderWarnings", true); */
+#else // Always suppress in release mode
+ png_error_ptr user_warning_fn = &do_nothing_warning_fn;
+#endif // defined(SK_DEBUG)
+
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
- NULL, sk_error_fn, NULL);
+ NULL, sk_error_fn, user_warning_fn);
// png_voidp user_error_ptr, user_error_fn, user_warning_fn);
if (png_ptr == NULL) {
return false;
}
+
*png_ptrp = png_ptr;
/* Allocate/initialize the memory for image information. */
@@ -498,9 +528,13 @@ bool SkPNGImageDecoder::getBitmapConfig(png_structp png_ptr, png_infop info_ptr,
transpColor->green >> 8,
transpColor->blue >> 8);
} else {
- *theTranspColorp = SkPackARGB32(0xFF, transpColor->red,
- transpColor->green,
- transpColor->blue);
+ /* We apply the mask because in a very small
+ number of corrupt PNGs, (transpColor->red > 255)
+ and (bitDepth == 8), for certain versions of libpng. */
+ *theTranspColorp = SkPackARGB32(0xFF,
+ 0xFF & (transpColor->red),
+ 0xFF & (transpColor->green),
+ 0xFF & (transpColor->blue));
}
} else { // gray
if (16 == bitDepth) {
@@ -508,9 +542,15 @@ bool SkPNGImageDecoder::getBitmapConfig(png_structp png_ptr, png_infop info_ptr,
transpColor->gray >> 8,
transpColor->gray >> 8);
} else {
- *theTranspColorp = SkPackARGB32(0xFF, transpColor->gray,
- transpColor->gray,
- transpColor->gray);
+ /* We apply the mask because in a very small
+ number of corrupt PNGs, (transpColor->red >
+ 255) and (bitDepth == 8), for certain versions
+ of libpng. For safety we assume the same could
+ happen with a grayscale PNG. */
+ *theTranspColorp = SkPackARGB32(0xFF,
+ 0xFF & (transpColor->gray),
+ 0xFF & (transpColor->gray),
+ 0xFF & (transpColor->gray));
}
}
}
« no previous file with comments | « src/images/SkImageDecoder_libjpeg.cpp ('k') | tests/JpegTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698