php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #77104 exif_read_data will fail with EOF on non-file streams containing large tags
Submitted: 2018-11-04 02:12 UTC Modified: -
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: magicaltux at gmail dot com Assigned:
Status: Open Package: EXIF related
PHP Version: 7.2.11 OS: Linux
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2018-11-04 02:12 UTC] magicaltux at gmail dot com
Description:
------------
exif_read_data() accepts a mixed $stream parameter to read from, however the source code makes use of php_stream_read() and will return a "Unexpected end of file reached" error if not enough bytes are returned.

However php_stream_read() when used on something else than a regular file (a seekable stream wrapper in my case) only perform a single call for 8192 bytes maximum, leaving ext/exif return a EOF error.

Two places in the code:

https://github.com/php/php-src/blob/master/ext/exif/exif.c#L3300
https://github.com/php/php-src/blob/master/ext/exif/exif.c#L3793

ext/exif should, in case php_stream_read() was able to read some but not all bytes, continue reading until nothing is read at all or requested data is read.

Test script:
---------------
(writing a specific test for this would require a lot of work as it'd need a stream wrapper/etc)

Actual result:
--------------
Warning: exif_read_data(): Unexpected end of file reached in test.php on line 9

Warning: exif_read_data(): Invalid TIFF file in test.php on line 9


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-11-04 02:28 UTC] magicaltux at gmail dot com
Some notes as I run more tests.

My failing file, a Photoshop generated TIFF, has the following large EXIF tags:

ExtensibleMetadataPlatform (17178 bytes)
ImageResourceInformation (5326 bytes)
ImageSourceData (1404340 bytes)

Using stream_set_chunk_size() to increase chunk size to a value higher than largest tag size (at 1.5MB) resolves issue but strongly affects performances as all reads are of that size.

Using stream_set_chunk_size() to set chunk size to 1 (from main/streams/streams.c in _php_stream_read() there is a check for stream->chunk_size == 1) then the read passed to the stream wrapper are no longer of a fixed chunk size but as requested by the caller. This resolves this issue without impacting performances too much.
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Wed Jul 24 07:01:26 2019 UTC