php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #70052 getimagesize() fails for very large and very small WBMP
Submitted: 2015-07-12 14:25 UTC Modified: 2015-07-23 22:01 UTC
From: p at wspnr dot com Assigned: cmb
Status: Closed Package: GetImageSize related
PHP Version: master-Git-2015-07-12 (Git) OS: Debian Linux
Private report: No CVE-ID:
 [2015-07-12 14:25 UTC] p at wspnr dot com
Description:
------------
1. getimagesize() seems to artificially limit the size of valid WBMPs to 2048x2048, even though imagecreatefromwbmp() will happily load WBMPs of arbitrary dimensions.

2. There is an integer overflow bug that occurs when the size of the supplied WBMP, as indicated in the header, is greater than (2^31-1) resulting in invalid WBMPs returning a "valid" response. This may cause problems for scripts that use getimagesize() to detect whether a file is an image or not.


Test script:
---------------
-- WBMP 1, 2047x2047 --
00 00 80 80 80 8F 7F 80 80 80 8F 7F

-- WBMP 2, 2048x2048 --
00 00 80 80 80 90 00 80 80 80 90 00

-- WBMP 3, 2049x2049 --
00 00 80 80 80 90 01 80 80 80 90 01

-- WBMP 4, (2^31)x(2^31) --
00 00 88 80 80 80 00 88 80 80 80 00

-- WBMP 5, (2^32-1)x(2^32-1) --
00 00 8F FF FF FF 7F 8F FF FF FF 7F

-- PHP --
<?php
for($i = 1; $i <= 5); ++$i) {
    echo "WBMP ", $i, PHP_EOL;
    var_dump(getimagesize("wbmp" . $i . ".wbmp"));
}

Expected result:
----------------
WBMP 1
array(5) {
  [0]=>
  int(2047)
  [1]=>
  int(2047)
  [2]=>
  int(15)
  [3]=>
  string(26) "width="2047" height="2047""
  ["mime"]=>
  string(18) "image/vnd.wap.wbmp"
}
WBMP 2
array(5) {
  [0]=>
  int(2048)
  [1]=>
  int(2048)
  [2]=>
  int(15)
  [3]=>
  string(26) "width="2048" height="2048""
  ["mime"]=>
  string(18) "image/vnd.wap.wbmp"
}
WBMP 3
bool(false)
WBMP 4
bool(false)
WBMP 5
bool(false)


Actual result:
--------------
WBMP 1
array(5) {
  [0]=>
  int(2047)
  [1]=>
  int(2047)
  [2]=>
  int(15)
  [3]=>
  string(26) "width="2047" height="2047""
  ["mime"]=>
  string(18) "image/vnd.wap.wbmp"
}
WBMP 2
array(5) {
  [0]=>
  int(2048)
  [1]=>
  int(2048)
  [2]=>
  int(15)
  [3]=>
  string(26) "width="2048" height="2048""
  ["mime"]=>
  string(18) "image/vnd.wap.wbmp"
}
WBMP 3
bool(false)
WBMP 4
array(5) {
  [0]=>
  int(2147483648)
  [1]=>
  int(2147483648)
  [2]=>
  int(15)
  [3]=>
  string(40) "width="-2147483648" height="-2147483648""
  ["mime"]=>
  string(18) "image/vnd.wap.wbmp"
}

WBMP 5
array(5) {
  [0]=>
  int(4294967295)
  [1]=>
  int(4294967295)
  [2]=>
  int(15)
  [3]=>
  string(22) "width="-1" height="-1""
  ["mime"]=>
  string(18) "image/vnd.wap.wbmp"
}

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-07-12 17:16 UTC] cmb@php.net
The size limitation of 2048x2048 has been introduced as fix[1] for
bug #29443. I'm not sure about the exact reasoning, but apparently
very large WBMPs can be considered rather uncommon, and obviously
the size restriction fixed the bug. 

[1] <https://github.com/php/php-src/commit/972940509f2c43adeb1723fd17584d3e992997ae>
 [2015-07-12 23:00 UTC] p at wspnr dot com
Best reason I can come up with is that the MPEG video file signature starts with "00 00 01 BA" which is the start of a valid WBMP header as well. That would result in a WBMP with a height of 7424 or greater.

Also, WBMPs smaller than 12 bytes produce a "Read error!".
 [2015-07-13 08:45 UTC] cmb@php.net
To my knowledge, MP4 files start with a 32bit number (big endian)
that tells the size of the first atom. It *might* be possible that
there are MP4 files which are mistaken for WBMP even though the
dimensions are restricted for "valid" WBMP files. And of course
it's always possible that there are some arbitrary binary files
which can be mistaken for WBMP.

It might be best to add a notice to the getimagesize() man page,
that this function should not be used to try to detect whether a
given file is an image file. finfo seems to be preferable for that
purpose, but even that is not bullet proof.

> Also, WBMPs smaller than 12 bytes produce a "Read error!".

Indeed! That's caused by
<https://github.com/php/php-src/blob/php-5.6.11/ext/standard/image.c#L1276-L1279>.
 [2015-07-13 11:45 UTC] p at wspnr dot com
That sounds reasonable, I could probably submit a documentation patch unless something is already being worked on.

However, I would still consider point #2 a bug. It should be possible to simply change the signed width and height to unsigned in php_get_wbmp().
 [2015-07-13 12:18 UTC] cmb@php.net
> [...] I could probably submit a documentation patch [...]

That would be nice. :)

> However, I would still consider point #2 a bug.

ACK

> It should be possible to simply change the signed width and
> height to unsigned in php_get_wbmp().

AIUI that wouldn't help much, as the dimensions of WBMP can be
arbitrary integer values, so we'd only delay the overflow. If, on
the other hand, we'd stick with the size restriction (2048**2), we
could simply bail out early if the width (resp. height) exceeds
2048[1].

And it might be reasonable to also avoid the "Read error" for WBMP
with less than 12 bytes. If I'm not mistaken, a WBMP of 8x7 is
only 11 bytes large.

[1] <https://github.com/php/php-src/blob/php-5.6.11/ext/standard/image.c#L971>
 [2015-07-13 12:40 UTC] p at wspnr dot com
Yep, I probably should have clarified that I was assuming the 2048x2048 limit stays. The width and height probably should be converted to unsigned anyways as the WBMP format uses unsigned ints as does the gfxinfo struct.

The 12-byte lower limit can be a problem for actual valid WBMPs, as it is a very compact format.
 [2015-07-23 14:48 UTC] cmb@php.net
-Status: Open +Status: Analyzed -Assigned To: +Assigned To: cmb
 [2015-07-23 16:05 UTC] cmb@php.net
-Summary: getimagesize() + WBMP integer overflow +Summary: getimagesize() fails for very large and very small WBMP
 [2015-07-23 16:46 UTC] cmb@php.net
Automatic comment on behalf of cmb
Revision: http://git.php.net/?p=php-src.git;a=commit;h=87829c09a1d9e39bee994460d7ccf19dd20eda14
Log: Fix #70052: getimagesize() fails for very large and very small WBMP
 [2015-07-23 16:46 UTC] cmb@php.net
-Status: Analyzed +Status: Closed
 [2015-07-23 21:16 UTC] p at wspnr dot com
I submitted the doc patch a while ago, but I think it's still in the queue.
 [2015-07-23 22:01 UTC] cmb@php.net
Thanks for the notice. I've committed your patch now. Thanks!
 [2015-08-04 20:54 UTC] ab@php.net
Automatic comment on behalf of cmb
Revision: http://git.php.net/?p=php-src.git;a=commit;h=87829c09a1d9e39bee994460d7ccf19dd20eda14
Log: Fix #70052: getimagesize() fails for very large and very small WBMP
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sat Jun 24 05:01:39 2017 UTC