[cairo] [PATCH] Generate better error message when loading invalid PNGs
Uli Schlachter
psychon at znc.in
Fri Mar 25 17:23:58 UTC 2016
Based on an idea from Cyril Roelandt, this patch makes cairo generate better
error messages when cairo_image_surface_create_from_png{,_stream} is called on
e.g. JPEG files. To do so, we don't let libpng check if the file starts with a
PNG signature, but do so by hand. On mismatch, a surface with status
CAIRO_STATUS_READ_ERROR is returned where previously the status was
CAIRO_STATUS_NO_MEMORY (the status used for all errors in libpng).
Additionally, a unit test is added for testing this, but only for
cairo_image_surface_create_from_png_stream().
Signed-off-by: Uli Schlachter <psychon at znc.in>
---
Hi Cyril, what do you think about this patch?
src/cairo-png.c | 8 ++++++++
test/create-from-png.c | 20 ++++++++++++++++++++
2 files changed, 28 insertions(+)
diff --git a/src/cairo-png.c b/src/cairo-png.c
index 068617d..e4356aa 100644
--- a/src/cairo-png.c
+++ b/src/cairo-png.c
@@ -549,6 +549,7 @@ read_png (struct png_read_closure_t *png_closure)
cairo_status_t status;
unsigned char *mime_data;
unsigned long mime_data_length;
+ png_byte png_magic[8];
png_closure->png_data = _cairo_memory_stream_create ();
@@ -578,6 +579,13 @@ read_png (struct png_read_closure_t *png_closure)
}
#endif
+ stream_read_func (png, png_magic, ARRAY_LENGTH (png_magic));
+ if (png_sig_cmp (png_magic, 0, ARRAY_LENGTH (png_magic))) {
+ surface = _cairo_surface_create_in_error (CAIRO_STATUS_READ_ERROR);
+ goto BAIL;
+ }
+ png_set_sig_bytes (png, ARRAY_LENGTH (png_magic));
+
png_read_info (png, info);
png_get_IHDR (png, info,
diff --git a/test/create-from-png.c b/test/create-from-png.c
index 2ca1fa2..1f18c47 100644
--- a/test/create-from-png.c
+++ b/test/create-from-png.c
@@ -42,6 +42,13 @@ read_error (void *closure, unsigned char *data, unsigned int size)
return CAIRO_STATUS_READ_ERROR;
}
+static cairo_status_t
+not_a_png (void *closure, unsigned char *data, unsigned int size)
+{
+ memset (data, 42, size);
+ return CAIRO_STATUS_SUCCESS;
+}
+
static cairo_test_status_t
draw (cairo_t *cr, int width, int height)
{
@@ -130,6 +137,19 @@ preamble (cairo_test_context_t *ctx)
if (result != CAIRO_TEST_SUCCESS)
return result;
+ surface = cairo_image_surface_create_from_png_stream (not_a_png, NULL);
+ if (cairo_surface_status (surface) != CAIRO_STATUS_READ_ERROR) {
+ result = cairo_test_status_from_status (ctx,
+ cairo_surface_status (surface));
+ if (result == CAIRO_TEST_FAILURE) {
+ cairo_test_log (ctx, "Error: expected \"read error\", but got: %s\n",
+ cairo_status_to_string (cairo_surface_status (surface)));
+ }
+ }
+ cairo_surface_destroy (surface);
+ if (result != CAIRO_TEST_SUCCESS)
+ return result;
+
/* cheekily test error propagation from the user write funcs as well ... */
xasprintf (&path, "%s/reference", ctx->srcdir);
xasprintf (&filename, "%s/%s", path, "create-from-png.ref.png");
--
2.8.0.rc3
More information about the cairo
mailing list