diff pidgin/gtkstatusbox.c @ 32138:e2c6e4fc3c84

Start looking at the GError parameter every time we call these functions: - gdk_pixbuf_loader_write - gdk_pixbuf_loader_close - gdk_pixbuf_new_from_file - gdk_pixbuf_new_from_file_at_size - gdk_pixbuf_new_from_file_at_scale There are times when gdkpixbuf returns a semi-invalid GdkPixbuf object and also sets the GError. If this happens we want to discard and ignore the GdkPixbuf object because it can cause problems. For example, calling gdk_pixbuf_scale_simple() causes gdkpixbuf to rapidly consume memory in an infinite loop. And that's bad. This commit adds some helper functions to gtkutils.[c|h] that make it a little easier to check the GError value. We should use them everywhere we call any of the above functions.
author Mark Doliner <mark@kingant.net>
date Wed, 22 Jun 2011 07:07:28 +0000
parents 17a4b32f4d46
children 904686722499
line wrap: on
line diff
--- a/pidgin/gtkstatusbox.c	Tue Jun 21 07:43:07 2011 +0000
+++ b/pidgin/gtkstatusbox.c	Wed Jun 22 07:07:28 2011 +0000
@@ -2225,22 +2225,45 @@
 
 	if (status_box->buddy_icon_img != NULL)
 	{
-		GdkPixbuf *buf, *scale;
-		int scale_width, scale_height;
-		GdkPixbufLoader *loader = gdk_pixbuf_loader_new();
+		GdkPixbufLoader *loader;
+		GError *error = NULL;
+
+		loader = gdk_pixbuf_loader_new();
+
 		g_signal_connect(G_OBJECT(loader), "size-prepared", G_CALLBACK(pixbuf_size_prepared_cb), NULL);
-		gdk_pixbuf_loader_write(loader, purple_imgstore_get_data(status_box->buddy_icon_img),
-		                        purple_imgstore_get_size(status_box->buddy_icon_img), NULL);
-		gdk_pixbuf_loader_close(loader, NULL);
-		buf = gdk_pixbuf_loader_get_pixbuf(loader);
-		scale_width = gdk_pixbuf_get_width(buf);
-		scale_height = gdk_pixbuf_get_height(buf);
-		scale = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, scale_width, scale_height);
-		gdk_pixbuf_fill(scale, 0x00000000);
-		gdk_pixbuf_copy_area(buf, 0, 0, scale_width, scale_height, scale, 0, 0);
-		if (pidgin_gdk_pixbuf_is_opaque(scale))
-			pidgin_gdk_pixbuf_make_round(scale);
-		status_box->buddy_icon = scale;
+		if (!gdk_pixbuf_loader_write(loader,
+				purple_imgstore_get_data(status_box->buddy_icon_img),
+				purple_imgstore_get_size(status_box->buddy_icon_img),
+				&error) || error)
+		{
+			purple_debug_warning("gtkstatusbox", "gdk_pixbuf_loader_write() "
+					"failed with size=%zu: %s\n",
+					purple_imgstore_get_size(status_box->buddy_icon_img),
+					error ? error->message : "(no error message)");
+			if (error)
+				g_error_free(error);
+		} else if (!gdk_pixbuf_loader_close(loader, &error) || error) {
+			purple_debug_warning("gtkstatusbox", "gdk_pixbuf_loader_close() "
+					"failed for image of size %zu: %s\n",
+					purple_imgstore_get_size(status_box->buddy_icon_img),
+					error ? error->message : "(no error message)");
+			if (error)
+				g_error_free(error);
+		} else {
+			GdkPixbuf *buf, *scale;
+			int scale_width, scale_height;
+
+			buf = gdk_pixbuf_loader_get_pixbuf(loader);
+			scale_width = gdk_pixbuf_get_width(buf);
+			scale_height = gdk_pixbuf_get_height(buf);
+			scale = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, scale_width, scale_height);
+			gdk_pixbuf_fill(scale, 0x00000000);
+			gdk_pixbuf_copy_area(buf, 0, 0, scale_width, scale_height, scale, 0, 0);
+			if (pidgin_gdk_pixbuf_is_opaque(scale))
+				pidgin_gdk_pixbuf_make_round(scale);
+			status_box->buddy_icon = scale;
+		}
+
 		g_object_unref(loader);
 	}