Jason Harrop created XGC-150:
--------------------------------

             Summary: ImageLoaderRawPNG never closes its ImageInputStream, so 
the image file stays open until garbage collection
                 Key: XGC-150
                 URL: https://issues.apache.org/jira/browse/XGC-150
             Project: XMLGraphicsCommons
          Issue Type: Bug
          Components: image codecs
    Affects Versions: 2.11
            Reporter: Jason Harrop
         Attachments: XGC-150.patch

{{ImageLoaderRawPNG.loadImage()}} takes the {{ImageInputStream}} out of the 
session's {{Source}}, detaches it with {{XmlSourceUtil.removeStreams(src)}} 
("Remove streams as we do things with them at some later time"), wraps it for 
{{PNGFile}}, and never closes it. But {{PNGFile}}'s constructor reads every 
chunk it keeps (IHDR, PLTE, IDAT, tRNS, iCCP, sRGB) into memory, and 
{{getImageRawPNG()}} serves the image data from those byte arrays, so nothing 
reads the stream once {{PNGFile}} has been constructed.

So after FOP renders a PNG (to PDF, say), the PNG's file stays open until the 
stream is garbage collected, and so does ImageIO's cache file ({{imageio*.tmp}} 
in {{java.io.tmpdir}}) where the source came from an {{InputStream}}. On 
Windows an open file can't be deleted, so an application can't remove the image 
files it has just rendered. Seen from docx4j 
(https://github.com/plutext/docx4j/issues/609), which writes pictures to 
temporary files for FOP and deletes them after the conversion: on Linux, 
{{/proc/self/fd}} still shows the PNG (deleted) and its {{imageio*.tmp}} open 
once FOP has finished, while a JPEG in the same document has been closed.

Fix: close the stream in a {{finally}} once {{PNGFile}} has read it:
{code:java}
        XmlSourceUtil.removeStreams(src);
        try {
            SeekableStream seekStream = new 
ImageInputStreamSeekableStreamAdapter(in);
            // PNGFile reads the chunks it needs into memory, so the stream is 
done with after this
            PNGFile im = new PNGFile(seekStream, info.getOriginalURI());
            return im.getImageRawPNG(info);
        } finally {
            IOUtils.closeQuietly(in);
        }
{code}
with a test, {{ImageLoaderRawPNGTestCase.testLoadImageClosesStream}}, which 
fails without the fix. The full test suite passes and checkstyle is clean. 
Patch attached; a PR follows.

Related: XGC-107 ({{ImageLoaderInternalTIFF}} doesn't close its source either).



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to