<html>
    <head>
      <base href="https://bugs.freedesktop.org/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Priority</th>
          <td>medium
          </td>
        </tr>

        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - cairo-1.12.14 - (Incorrectly?) treat libpng warnings as error, causing issues in applications"
   href="https://bugs.freedesktop.org/show_bug.cgi?id=63359">63359</a>
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>cworth@cworth.org
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>cairo-1.12.14 - (Incorrectly?) treat libpng warnings as error, causing issues in applications
          </td>
        </tr>

        <tr>
          <th>QA Contact</th>
          <td>cairo-bugs@cairographics.org
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>pyxlcy@gmail.com
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>Other
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>1.12.14
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>png functions
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>cairo
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Problem:

When reading a PNG file, cairo treats libpng warnings as errors.

cairo-1.12.12/src/cairo-png.c:
----
static void
png_simple_warning_callback (png_structp png,
                         png_const_charp error_msg)
{
    cairo_status_t *error = png_get_error_ptr (png);

    /* default to the most likely error */
    if (*error == CAIRO_STATUS_SUCCESS)
    *error = _cairo_error (CAIRO_STATUS_NO_MEMORY);

    /* png does not expect to abort and will try to tidy up after a warning */
}

// ...

static cairo_surface_t *
read_png (struct png_read_closure_t *png_closure)
{

// ...
    png = png_create_read_struct (PNG_LIBPNG_VER_STRING,
                                  &status,
                              png_simple_error_callback,
                              png_simple_warning_callback);

// ...
    if (unlikely (status)) { /* catch any early warnings */
    surface = _cairo_surface_create_in_error (status);
    goto BAIL;
    }
----

This prevents some PNGs with problems to be loaded with
cairo_image_surface_create_from_png(). Not sure if it's intentional or a
mistake, but it's causing breakages in fcitx-4.2.7 recently.

How to reproduce the issue:

Here's slightly broken PNG image, included in fcitx-4.2.7:
<a href="https://raw.github.com/fcitx/fcitx/be9f3af1aa5eb4e037ba6e6dee098edb7e41e9cc/skin/default/cn.png">https://raw.github.com/fcitx/fcitx/be9f3af1aa5eb4e037ba6e6dee098edb7e41e9cc/skin/default/cn.png</a>

Small test program to load a PNG with cairo, taken from <
<a href="http://permalink.gmane.org/gmane.comp.lib.cairo/23741">http://permalink.gmane.org/gmane.comp.lib.cairo/23741</a> >:
----
#include <stdio.h>
#include <cairo/cairo.h>

int main(int argc, char *argv[])
{
  cairo_surface_t *surface;

  surface = cairo_image_surface_create_from_png(argv[1]);
  if (cairo_surface_status(surface))  
    fprintf(stderr, "Error reading PNG image %s: %s\n",
            argv[1], cairo_status_to_string (cairo_surface_status(surface)));
  else
    fprintf(stderr, "PNG image read.\n");

  return 0;
}
----

With <libpng-1.6, cairo loads this image correctly; with libpng-1.6.1, cairo
complains "Error reading PNG image cn.png: out of memory". (There's another
issue regarding libpng-1.6, #62779, that could cause the same result, and the
patch there needs to be applied firstly.)

Background - fcitx-4.2.7 segfaults because of the problem:

After upgrading to libpng-1.6.1, I found fcitx segfaulting immediately after
execution. It looks like an issue in cairo and applying the patch from #62779
to cairo-1.12.12 fixed it. But later I found fcitx is still segfaulting
sometimes, because it fails to load some particular PNG files with
cairo_image_surface_create_from_png() and it isn't handling the failure
gracefully. The PNG file used to work correctly with cairo and libpng-1.5, but
with libpng-1.6.1 cairo could no longer load it. Further debugging reveals
cairo refuses to load the file because libpng-1.6.1 emits a warning:

----
Breakpoint 5, png_simple_warning_callback (png=0x555555759c00, 
    error_msg=0x7fffffffd870 "iCCP: known incorrect sRGB profile") at
cairo-png.c:151
----

"iCCP: known incorrect sRGB profile" isn't actually a fatal issue in a PNG
file, and <libpng-1.6 probably doesn't emit this warning. Yet since cairo
treats libpng warnings as errors, it refuses to the load the file.

I've already reported the issue to fcitx devs <
<a href="http://code.google.com/p/fcitx/issues/detail?id=678">http://code.google.com/p/fcitx/issues/detail?id=678</a> >, but there are many,
many, PNGs in the world that are just slightly broken. Maybe cairo could be a
little more tolerant on libpng warnings? I'm personally using a custom patch to
ignore libpng warnings in png_simple_warning_callback() as a workaround.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are the QA Contact for the bug.</li>
      </ul>
    </body>
</html>