After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 739785 - gdk_pixbuf_animation_new_from_file assert on malformed PNG file
gdk_pixbuf_animation_new_from_file assert on malformed PNG file
Status: RESOLVED FIXED
Product: gdk-pixbuf
Classification: Platform
Component: loaders
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gdk-pixbuf-maint
gdk-pixbuf-maint
Depends on:
Blocks:
 
 
Reported: 2014-11-07 14:46 UTC by Hanno Böck
Modified: 2016-10-08 11:52 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
crash.png (3.63 KB, image/png)
2014-11-07 14:47 UTC, Hanno Böck
Details
gdk-crash.c (180 bytes, text/plain)
2014-11-07 14:47 UTC, Hanno Böck
Details
2-byte-file to cause assert (2 bytes, image/png)
2014-11-09 10:13 UTC, Hanno Böck
Details
full backtrace (3.22 KB, text/plain)
2014-11-15 19:49 UTC, Michael Schwendt
Details

Description Hanno Böck 2014-11-07 14:46:57 UTC
When gdk_pixbuf_animation_new_from_file() is called on a malformed PNG file this will cause an assert. This has the potential to crash applications (I first encountered this in claws-mail).

See attached sample code:
* Compile: gcc `pkg-config --libs --cflags glib-2.0 gdk-pixbuf-2.0` gdk-crash.c -o gdk-crash
* Run on good PNG file: ./gdk-crash good.png - nothing happens
* Run on bad PNG file: ./gdk-crash crash.png - assert

I'll attack gdk-crash.c and crash.png.
Comment 1 Hanno Böck 2014-11-07 14:47:12 UTC
Created attachment 290173 [details]
crash.png
Comment 2 Hanno Böck 2014-11-07 14:47:39 UTC
Created attachment 290174 [details]
gdk-crash.c
Comment 3 Matthias Clasen 2014-11-07 18:04:20 UTC
doesn't crash here. can you provide a stacktrace ?
Comment 4 Hanno Böck 2014-11-07 18:40:40 UTC
gdb backtrace:

GdkPixbuf:ERROR:/var/tmp/portage/x11-libs/gdk-pixbuf-2.30.8/work/gdk-pixbuf-2.30.8/gdk-pixbuf/gdk-pixbuf-animation.c:250:gdk_pixbuf_animation_new_from_file: assertion failed: (animation)

Program received signal SIGABRT, Aborted.
0x00007ffff70a6237 in raise () from /lib64/libc.so.6
(gdb) bt
  • #0 raise
    from /lib64/libc.so.6
  • #1 abort
    from /lib64/libc.so.6
  • #2 g_assertion_message
    from /usr/lib64/libglib-2.0.so.0
  • #3 g_assertion_message_expr
    from /usr/lib64/libglib-2.0.so.0
  • #4 gdk_pixbuf_animation_new_from_file
    from /usr/lib64/libgdk_pixbuf-2.0.so.0
  • #5 main

Comment 5 Hanno Böck 2014-11-09 10:12:38 UTC
I re-tried this with latest git head code and can reproduce it there also. It can also be triggered with a much smaller example, just a 2-byte-file.
Comment 6 Hanno Böck 2014-11-09 10:13:35 UTC
Created attachment 290267 [details]
2-byte-file to cause assert
Comment 7 Matthias Clasen 2014-11-10 14:25:31 UTC
still doesn't crash here :-(
Comment 8 Michael Schwendt 2014-11-15 19:49:41 UTC
Created attachment 290771 [details]
full backtrace

Full backtrace attached. Generated with Fedora 21 (x86_64).

Using the "malformed png file":
http://www.thewildbeast.co.uk/claws-mail/bugzilla/attachment.cgi?id=1447

$ gcc -g test.c -o test $(pkg-config --cflags --libs gdk-pixbuf-2.0)
$ ./test 2670-sample.png 
**
GdkPixbuf:ERROR:gdk-pixbuf-animation.c:250:gdk_pixbuf_animation_new_from_file: assertion failed: (animation)
Aborted (core dumped)
Comment 9 Michael Schwendt 2014-11-16 12:43:43 UTC
The problem being that the "animation" ptr is initialized to NULL in line 222 prior to loading the image, and later on up to end-of-file it does not receive any value, so the assertion in line 250 doesn't hold true:

   215          } else if (image_module->begin_load != NULL) {

   222                  animation = NULL;

   225                  context = image_module->begin_load (NULL, prepared_notif
y, NULL, &animation, error);
   226                  if (!context)
   227                          goto fail_begin_load;
   228                  
   229                  while (!feof (f) && !ferror (f)) {
   230                          length = fread (buffer, 1, sizeof (buffer), f);
   231                          if (length > 0) {
   232                                  if (!image_module->load_increment (conte
xt, buffer, length, error)) {
   233                                          error = NULL;
   234                                          goto fail_load_increment;
   235                                  }
   236                          }
   237                  }
   238  
   239                  success = TRUE;
   240  
   241  fail_load_increment:
   242                  if (!image_module->stop_load (context, error))
   243                          success = FALSE;
   244  
   245  fail_begin_load:
   246                  fclose (f);
   247  
   248                  if (success) {
   249                          /* If there was no error, there must be an animation that was successfully loaded */
   250                          g_assert (animation);
Comment 10 Hanno Böck 2016-10-08 11:52:31 UTC
I can no longer reproduce this, so I assume this has been fixed in the meantime.