[gdk-pixbuf/wip/rishi/png] io-png: Clarify and fix the error handling
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gdk-pixbuf/wip/rishi/png] io-png: Clarify and fix the error handling
- Date: Wed, 12 Sep 2018 11:54:37 +0000 (UTC)
commit aa7d203ec63ed1e14ac558415b26fe3e42ab8e44
Author: Debarshi Ray <debarshir gnome org>
Date: Sun Sep 9 20:26:22 2018 +0200
io-png: Clarify and fix the error handling
Neither png_create_read_struct* nor png_create_info_struct can trigger
a longjmp out of libpng. That's only documented as being possible with
png_set_progressive_read_fn, even though, currently, it does not.
The documentation [1] is being a bit simplistic when it says:
"... you will need to update the jmpbuf field every time you enter a
new routine that will call a png_*() function"
On closer look, the documentation for png_create_read_struct* [2] and
png_create_info_struct [3] clarify that they return NULL on error and
not longjmp. This is borne out by the libpng code, comments and
examples.
The current location of the setjmp is confusing to the reader because
one can be misled into thinking that there's no need to check the
value returned by png_create_info_struct, or that a failure will lead
to the error handler and a longjmp.
In light of this, the assumption that the error callback would set the
GError when either png_create_read_struct* or png_create_info_struct
fails is wrong. These functions can only fail if there was a request
to allocate an absurdly large amount of memory that exceeds one of
limits encoded in libpng; or if the memory allocator returns NULL; or
if there was a ABI mismatch caused by compiling and running against
incompatible libpng versions. All those are programming or
integration errors, and normally one wouldn't bother handling them.
However, since the libpng documentation repeatedly mentions that the
return value from these functions should be checked, it's wise to do
so.
Fallout from e8d0d8ed3d33ee6cedb75a394c36af3312b310ff
[1] http://www.libpng.org/pub/png/libpng-1.2.5-manual.html#section-3
[2]
http://refspecs.linuxbase.org/LSB_4.1.0/LSB-Desktop-generic/LSB-Desktop-generic/libpng12.png.create.read.struct.1.html
[3]
http://refspecs.linuxbase.org/LSB_4.1.0/LSB-Desktop-generic/LSB-Desktop-generic/libpng12.png.create.info.struct.1.html
gdk-pixbuf/io-png.c | 36 ++++++++++++++++++++++++++++--------
1 file changed, 28 insertions(+), 8 deletions(-)
---
diff --git a/gdk-pixbuf/io-png.c b/gdk-pixbuf/io-png.c
index 06cf36595..e39b1ecb7 100644
--- a/gdk-pixbuf/io-png.c
+++ b/gdk-pixbuf/io-png.c
@@ -483,16 +483,19 @@ gdk_pixbuf__png_image_begin_load (GdkPixbufModuleSizeFunc size_func,
#endif
if (lc->png_read_ptr == NULL) {
g_free(lc);
- /* error callback should have set the error */
+
+ /* A failure here isn't supposed to call the error
+ * callback, but it doesn't hurt to be careful.
+ */
+ if (error && *error == NULL) {
+ g_set_error_literal (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
+ _("Couldn’t allocate memory for loading PNG"));
+ }
+
return NULL;
}
-
- if (setjmp (png_jmpbuf(lc->png_read_ptr))) {
- png_destroy_read_struct(&lc->png_read_ptr, &lc->png_info_ptr, NULL);
- g_free(lc);
- /* error callback should have set the error */
- return NULL;
- }
/* Create the auxiliary context struct */
@@ -501,6 +504,23 @@ gdk_pixbuf__png_image_begin_load (GdkPixbufModuleSizeFunc size_func,
if (lc->png_info_ptr == NULL) {
png_destroy_read_struct(&lc->png_read_ptr, NULL, NULL);
g_free(lc);
+
+ /* A failure here isn't supposed to call the error
+ * callback, but it doesn't hurt to be careful.
+ */
+ if (error && *error == NULL) {
+ g_set_error_literal (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
+ _("Couldn’t allocate memory for loading PNG"));
+ }
+
+ return NULL;
+ }
+
+ if (setjmp (png_jmpbuf(lc->png_read_ptr))) {
+ png_destroy_read_struct(&lc->png_read_ptr, &lc->png_info_ptr, NULL);
+ g_free(lc);
/* error callback should have set the error */
return NULL;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]