From 64e5c7632385cdb73b0dd7a7c7cd5ce48f6a8007 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sat, 30 Dec 2023 20:14:10 +0100 Subject: [PATCH] png: Don't set a size limit when saving gdk_texture_save_to_png_bytes() cannot fail, so ensure that it doesn't. Testsuite has been updated to check for this case. Note that we do not load the PNG file that we generate here. Loading is a lot more scary than saving after all. If people want to load oversized PNG files, they should use a real PNG loader. --- gdk/loaders/gdkpng.c | 3 +++ testsuite/gdk/texture.c | 29 ++++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/gdk/loaders/gdkpng.c b/gdk/loaders/gdkpng.c index aca5d48fdb..c2de26fd32 100644 --- a/gdk/loaders/gdkpng.c +++ b/gdk/loaders/gdkpng.c @@ -419,6 +419,9 @@ gdk_save_png (GdkTexture *texture) if (!png) return NULL; + /* 2^31-1 is the maximum size for PNG files */ + png_set_user_limits (png, (1u << 31) - 1, (1u << 31) - 1); + info = png_create_info_struct (png); if (!info) { diff --git a/testsuite/gdk/texture.c b/testsuite/gdk/texture.c index eeb879294e..0e503e514d 100644 --- a/testsuite/gdk/texture.c +++ b/testsuite/gdk/texture.c @@ -39,6 +39,29 @@ compare_pixels (int width, } } +static GdkTexture * +red_texture_new (int width, + int height) +{ + /* We use GDK_MEMORY_R8G8B8A8 here because it's the expected PNG RGBA format */ + const GdkMemoryFormat format = GDK_MEMORY_R8G8B8A8; + int i; + guint32 *data; + GBytes *bytes; + GdkTexture *texture; + + data = g_malloc (width * height * 4); + + for (i = 0; i < width * height; i++) + data[i] = 0xFF0000FF; + + bytes = g_bytes_new_take ((guint8 *) data, width * height * 4); + texture = gdk_memory_texture_new (width, height, format, bytes, width * 4); + g_bytes_unref (bytes); + + return texture; +} + static void compare_textures (GdkTexture *texture1, GdkTexture *texture2) @@ -146,7 +169,7 @@ test_texture_save_to_png (void) texture = gdk_texture_new_from_resource ("/org/gtk/libgtk/icons/16x16/places/user-trash.png"); - gdk_texture_save_to_png (texture, "test.png"); + g_assert_true (gdk_texture_save_to_png (texture, "test.png")); file = g_file_new_for_path ("test.png"); texture2 = gdk_texture_new_from_file (file, &error); g_object_unref (file); @@ -156,6 +179,10 @@ test_texture_save_to_png (void) g_object_unref (texture); g_object_unref (texture2); + + /* libpng has a builtin user limit of 1M pixels per dimension, so we make it 1px too big. */ + texture = red_texture_new (1 * 1000 * 1000 + 1, 1); + g_assert_true (gdk_texture_save_to_png (texture, "test.png")); } static void