diff options
author | Christoph M. Becker <cmbecker69@gmx.de> | 2016-08-13 16:02:10 +0200 |
---|---|---|
committer | Christoph M. Becker <cmbecker69@gmx.de> | 2016-08-13 16:14:34 +0200 |
commit | 82df4e263886a0da21a00c98189649287666ba5c (patch) | |
tree | e77ee1fbcfcc8fc397b94cf9bcccafd9b73c78ab /ext/standard/image.c | |
parent | ae3b2078eac226c61bc325527e607ad275936d22 (diff) | |
download | php-git-82df4e263886a0da21a00c98189649287666ba5c.tar.gz |
Fix #72278: getimagesize returning FALSE on valid jpg
getimagesize() is rather strict about the length of the marker payload data,
and fails if there are extraneous bytes before the next marker. Only a very
special case reported in bug #13213 is catered to.
libjpeg is rather resilient to such corrupted JPEG files, and raises a
recoverable error in this case. Other image processors also accept such
JPEG files, so we adapt getimagesize() to skip (but warn about) such
extraneous bytes.
Diffstat (limited to 'ext/standard/image.c')
-rw-r--r-- | ext/standard/image.c | 42 |
1 files changed, 15 insertions, 27 deletions
diff --git a/ext/standard/image.c b/ext/standard/image.c index f20482bde4..d58d543abd 100644 --- a/ext/standard/image.c +++ b/ext/standard/image.c @@ -374,48 +374,36 @@ static unsigned short php_read2(php_stream * stream TSRMLS_DC) /* {{{ php_next_marker * get next marker byte from file */ -static unsigned int php_next_marker(php_stream * stream, int last_marker, int comment_correction, int ff_read TSRMLS_DC) +static unsigned int php_next_marker(php_stream * stream, int last_marker, int ff_read TSRMLS_DC) { int a=0, marker; /* get marker byte, swallowing possible padding */ - if (last_marker==M_COM && comment_correction) { - /* some software does not count the length bytes of COM section */ - /* one company doing so is very much envolved in JPEG... so we accept too */ - /* by the way: some of those companies changed their code now... */ - comment_correction = 2; - } else { - last_marker = 0; - comment_correction = 0; - } - if (ff_read) { - a = 1; /* already read 0xff in filetype detection */ + if (!ff_read) { + size_t extraneous = 0; + + while ((marker = php_stream_getc(stream)) != 0xff) { + if (marker == EOF) { + return M_EOI;/* we hit EOF */ + } + extraneous++; + } + if (extraneous) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "corrupt JPEG data: %zu extraneous bytes before marker", extraneous); + } } + a = 1; do { if ((marker = php_stream_getc(stream)) == EOF) { return M_EOI;/* we hit EOF */ } - if (last_marker==M_COM && comment_correction>0) - { - if (marker != 0xFF) - { - marker = 0xff; - comment_correction--; - } else { - last_marker = M_PSEUDO; /* stop skipping non 0xff for M_COM */ - } - } a++; } while (marker == 0xff); if (a < 2) { return M_EOI; /* at least one 0xff is needed before marker code */ } - if ( last_marker==M_COM && comment_correction) - { - return M_EOI; /* ah illegal: char after COM section not 0xFF */ - } return (unsigned int)marker; } /* }}} */ @@ -478,7 +466,7 @@ static struct gfxinfo *php_handle_jpeg (php_stream * stream, zval *info TSRMLS_D unsigned short length, ff_read=1; for (;;) { - marker = php_next_marker(stream, marker, 1, ff_read TSRMLS_CC); + marker = php_next_marker(stream, marker, ff_read TSRMLS_CC); ff_read = 0; switch (marker) { case M_SOF0: |