Re: Infinite loop at EOF in libpng

Bob Friesenhahn <[email protected]> Tue, 25 May 2021 12:59:52 -0500 (CDT)
Newsgroups gmane.comp.graphics.png.devel
Message-ID <[email protected]>
On Tue, 25 May 2021, Björn Ganster wrote:

> Hi all,
>
> I'm Björn Ganster, working for X-Ways Software Technology AG. We use libpng 
> as part of our software to display images of all kinds via ResIL 
> (https://sourceforge.net/projects/resil/), which requires us to also support 
> image files in various states of decay (e.g., files that are cut off or where 
> the ending has been overwritten by junk).
>
> Normally, libpng works very well for us. However, I have been sent a file 
> that leads to an infinite loop in libpng. This file is obviously not a normal 
> png, it seems that the file end is missing. ResIL provides a callback 
> function for reading data, and libpng's png_read_data funtion in pngrio.c 
> calls this function. The problem here is that the callback function has no 
> way of indicating that less than the required number of bytes is available, 
> and so of course libpng cannot check whether the read request was fully 
> handled. In the case at hand, the callback refuses to read any bytes beyond 
> and of file (EOF), leading to an infinite loop between libpng and the 
> callback. I was able to reach an error state with this png file by setting

Does your callback invoke png_error()?  I notice that the default 
function png_default_read_data() invokes "png_error(png_ptr, "Read 
Error");" on a short read.

It is common for libpng-related error handling to be done via 
setjmp()/longjmp(), which allows restoring the state at some point in 
the call stack.  It seems that you can register your own png_error_ptr 
callback so that png_error() then invokes your own callback.

I agree that it is odd that the I/O callback does not return the 
number of bytes read.  It appears that the strategy is that the I/O 
callback calls png_error(), which invokes your own registered callback 
to then use longjmp() to unwind to a certain point, or quit entirely.

Given that PNGs should be read linearly, it makes sense to stop 
attempting to read as soon as EOF is detected.

Bob
-- 
Bob Friesenhahn
[email protected], http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,    http://www.GraphicsMagick.org/
Public Key,     http://www.simplesystems.org/users/bfriesen/public-key.txt

_______________________________________________
png-mng-implement mailing list
png-mng-implement-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/png-mng-implement