php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #75708 getimagesize with "&$imageinfo" fails on StreamWrappers
Submitted: 2017-12-20 02:54 UTC Modified: 2023-10-15 16:02 UTC
Votes:7
Avg. Score:3.9 ± 1.5
Reproduced:5 of 5 (100.0%)
Same Version:3 (60.0%)
Same OS:1 (20.0%)
From: joehoyle at gmail dot com Assigned: bukka (profile)
Status: Closed Package: Streams related
PHP Version: 7.1.12 OS: Alpine Linux
Private report: No CVE-ID: None
 [2017-12-20 02:54 UTC] joehoyle at gmail dot com
Description:
------------
When using getimagesize( $path, $imageinfo ) on specific images in conjunction with a custom StreamWrapper path, multiple "PHP Warning:  getimagesize(): corrupt JPEG data: 536 extraneous bytes before marker in..." errors are shown, and the $imageinfo is empty.

This also happens with a "fake filesystem streamwrapper" as demonstrated.

Test script:
---------------
https://gist.github.com/joehoyle/b9484e6375ce3a1d4cbefe5e439ef80d

Using image: https://joehoyle-captured.s3.amazonaws.com/test.jpg

Expected result:
----------------
bool(true)
bool(true)
[20-Dec-2017 02:51:20 UTC] PHP Warning:  getimagesize(): corrupt JPEG data: 183 extraneous bytes before marker in /usr/src/app/test.php on line 60
[20-Dec-2017 02:51:20 UTC] PHP Warning:  getimagesize(): corrupt JPEG data: 140 extraneous bytes before marker in /usr/src/app/test.php on line 60
[20-Dec-2017 02:51:20 UTC] PHP Warning:  getimagesize(): corrupt JPEG data: 175 extraneous bytes before marker in /usr/src/app/test.php on line 60
[20-Dec-2017 02:51:20 UTC] PHP Warning:  getimagesize(): corrupt JPEG data: 854 extraneous bytes before marker in /usr/src/app/test.php on line 60
[20-Dec-2017 02:51:20 UTC] PHP Warning:  getimagesize(): corrupt JPEG data: 723 extraneous bytes before marker in /usr/src/app/test.php on line 60
[20-Dec-2017 02:51:20 UTC] PHP Warning:  getimagesize(): corrupt JPEG data: 31 extraneous bytes before marker in /usr/src/app/test.php on line 60
[20-Dec-2017 02:51:20 UTC] PHP Warning:  getimagesize(): corrupt JPEG data: 79 extraneous bytes before marker in /usr/src/app/test.php on line 60
[20-Dec-2017 02:51:20 UTC] PHP Warning:  getimagesize(): corrupt JPEG data: 502 extraneous bytes before marker in /usr/src/app/test.php on line 60
[20-Dec-2017 02:51:20 UTC] PHP Warning:  getimagesize(): corrupt JPEG data: 48 extraneous bytes before marker in /usr/src/app/test.php on line 60
[20-Dec-2017 02:51:20 UTC] PHP Warning:  getimagesize(): corrupt JPEG data: 116 extraneous bytes before marker in /usr/src/app/test.php on line 60
[20-Dec-2017 02:51:20 UTC] PHP Warning:  getimagesize(): corrupt JPEG data: 295 extraneous bytes before marker in /usr/src/app/test.php on line 60
[20-Dec-2017 02:51:20 UTC] PHP Warning:  getimagesize(): corrupt JPEG data: 710 extraneous bytes before marker in /usr/src/app/test.php on line 60
[20-Dec-2017 02:51:20 UTC] PHP Warning:  getimagesize(): corrupt JPEG data: 536 extraneous bytes before marker in /usr/src/app/test.php on line 60
done

Actual result:
--------------
bool(true)
bool(true)
done

Patches

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-12-20 16:18 UTC] cmb@php.net
-Status: Open +Status: Verified
 [2017-12-20 16:18 UTC] cmb@php.net
I can confirm the erroneous behavior.  Interestingly, calling
getimagesize() without the second parameter succeeds without
warnings.  The only relevant difference is that the info parameter
causes php_read_APP() to be called, while without info parameter
php_skip_variable() is called[1].  However, the relevant
difference between php_skip_variable()[2] and php_read_APP()[3] is
that the former calls php_stream_seek() while the latter calls
php_stream_read() (both with the same offset/length).  Apparently,
there is an issue regarding php_stream_read(); possibly related to
bug #72561.

[1] <https://github.com/php/php-src/blob/PHP-7.2.0/ext/standard/image.c#L535-L543>
[2] <https://github.com/php/php-src/blob/PHP-7.2.0/ext/standard/image.c#L424-L437>
[3] <https://github.com/php/php-src/blob/PHP-7.2.0/ext/standard/image.c#L439-L471>
 [2023-09-23 20:41 UTC] bukka@php.net
-Assigned To: +Assigned To: bukka
 [2023-09-23 20:41 UTC] bukka@php.net
I have spent quite a bit of time on this today and the reason is that stream wrapper does not use greedy reading so not the whole length is returned if the chunk is read full. This happens only for some images so I will need to figure the pattern out as I'm able to recreate only for really big images which is not convenient for test addition. Otherwise I have got a fix in https://github.com/bukka/php-src/commit/88a8095a20c6598cdf6e3ce0b2a6849fb58c5a8b but need to finish the test as I said.

The whole stream handling seems a bit incomplete as even with var it does not check seek return value which is not probably right. The whole handling needs more looking and investigation and some follow up fixes are likely.
 [2023-10-15 15:58 UTC] bukka@php.net
The following pull request has been associated:

Patch Name: Fix bug #75708: getimagesize with "&$imageinfo" fails on StreamWrappers
On GitHub:  https://github.com/php/php-src/pull/12444
Patch:      https://github.com/php/php-src/pull/12444.patch
 [2023-10-15 16:01 UTC] bukka@php.net
The pattern is that it needs to be image with large APPn data (larger than one stream chunk). I managed to create easily that file with GIMP by creating small image and editing its metadata to contain very large description text (just added long lorem ipsum).
 [2023-10-15 16:02 UTC] bukka@php.net
The PR is attached. Most work was really to debug the whole thing which is quite usual for stream related things.
 [2023-10-22 12:28 UTC] git@php.net
Automatic comment on behalf of bukka
Revision: https://github.com/php/php-src/commit/52aa0d9ecc7ab8b0b74f142e7c1020caa281fbba
Log: Fix bug #75708: getimagesize with &quot;&amp;$imageinfo&quot; fails on StreamWrappers
 [2023-10-22 12:28 UTC] git@php.net
-Status: Verified +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 12:01:31 2024 UTC