summaryrefslogtreecommitdiff
path: root/ext/standard/image.c
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2016-08-13 16:02:10 +0200
committerChristoph M. Becker <cmbecker69@gmx.de>2016-08-13 16:14:34 +0200
commit82df4e263886a0da21a00c98189649287666ba5c (patch)
treee77ee1fbcfcc8fc397b94cf9bcccafd9b73c78ab /ext/standard/image.c
parentae3b2078eac226c61bc325527e607ad275936d22 (diff)
downloadphp-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.c42
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: