Skip to content

Commit cd8d0aa

Browse files
committed
Fixed bug #50660 (exif_read_data(): Illegal IFD offset (works fine with other exif readers))
1 parent 900ce92 commit cd8d0aa

File tree

5 files changed

+32
-7
lines changed

5 files changed

+32
-7
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ PHP NEWS
1313
- EXIF:
1414
. Fixed bug #74428 (exif_read_data(): "Illegal IFD size" warning occurs with
1515
correct exif format). (bradpiccho at gmail dot com, Kalle)
16+
. Fixed bug #50660 (exif_read_data(): Illegal IFD offset (works fine with
17+
other exif readers). (skinny dot bravo at gmail dot com, Kalle)
1618

1719
- GD:
1820
. Fixed bug #74435 (Buffer over-read into uninitialized memory). (cmb)

ext/exif/exif.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2677,7 +2677,7 @@ static void exif_process_SOFn (uchar *Data, int marker, jpeg_sof_info *result)
26772677
/* }}} */
26782678

26792679
/* forward declarations */
2680-
static int exif_process_IFD_in_JPEG(image_info_type *ImageInfo, char *dir_start, char *offset_base, size_t IFDlength, size_t displacement, int section_index);
2680+
static int exif_process_IFD_in_JPEG(image_info_type *ImageInfo, char *dir_start, char *offset_base, size_t IFDlength, size_t displacement, int section_index, int tag);
26812681
static int exif_process_IFD_TAG( image_info_type *ImageInfo, char *dir_entry, char *offset_base, size_t IFDlength, size_t displacement, int section_index, int ReadNextIFD, tag_table_type tag_table);
26822682

26832683
/* {{{ exif_get_markername
@@ -3524,7 +3524,7 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
35243524
exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Illegal IFD Pointer");
35253525
return FALSE;
35263526
}
3527-
if (!exif_process_IFD_in_JPEG(ImageInfo, Subdir_start, offset_base, IFDlength, displacement, sub_section_index)) {
3527+
if (!exif_process_IFD_in_JPEG(ImageInfo, Subdir_start, offset_base, IFDlength, displacement, sub_section_index, tag)) {
35283528
return FALSE;
35293529
}
35303530
#ifdef EXIF_DEBUG
@@ -3541,11 +3541,11 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
35413541

35423542
/* {{{ exif_process_IFD_in_JPEG
35433543
* Process one of the nested IFDs directories. */
3544-
static int exif_process_IFD_in_JPEG(image_info_type *ImageInfo, char *dir_start, char *offset_base, size_t IFDlength, size_t displacement, int section_index)
3544+
static int exif_process_IFD_in_JPEG(image_info_type *ImageInfo, char *dir_start, char *offset_base, size_t IFDlength, size_t displacement, int section_index, int tag)
35453545
{
35463546
int de;
35473547
int NumDirEntries;
3548-
int NextDirOffset;
3548+
int NextDirOffset = 0;
35493549

35503550
#ifdef EXIF_DEBUG
35513551
exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Process %s (x%04X(=%d))", exif_get_sectionname(section_index), IFDlength, IFDlength);
@@ -3585,7 +3585,11 @@ static int exif_process_IFD_in_JPEG(image_info_type *ImageInfo, char *dir_start,
35853585
exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Illegal IFD size");
35863586
return FALSE;
35873587
}
3588-
NextDirOffset = php_ifd_get32u(dir_start+2+12*de, ImageInfo->motorola_intel);
3588+
3589+
if (tag != TAG_EXIF_IFD_POINTER && tag != TAG_GPS_IFD_POINTER) {
3590+
NextDirOffset = php_ifd_get32u(dir_start+2+12*de, ImageInfo->motorola_intel);
3591+
}
3592+
35893593
if (NextDirOffset) {
35903594
/* the next line seems false but here IFDlength means length of all IFDs */
35913595
if (offset_base + NextDirOffset < offset_base || offset_base + NextDirOffset > offset_base+IFDlength) {
@@ -3596,7 +3600,7 @@ static int exif_process_IFD_in_JPEG(image_info_type *ImageInfo, char *dir_start,
35963600
#ifdef EXIF_DEBUG
35973601
exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Expect next IFD to be thumbnail");
35983602
#endif
3599-
if (exif_process_IFD_in_JPEG(ImageInfo, offset_base + NextDirOffset, offset_base, IFDlength, displacement, SECTION_THUMBNAIL)) {
3603+
if (exif_process_IFD_in_JPEG(ImageInfo, offset_base + NextDirOffset, offset_base, IFDlength, displacement, SECTION_THUMBNAIL, 0)) {
36003604
#ifdef EXIF_DEBUG
36013605
exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Thumbnail size: 0x%04X", ImageInfo->Thumbnail.size);
36023606
#endif
@@ -3651,7 +3655,7 @@ static void exif_process_TIFF_in_JPEG(image_info_type *ImageInfo, char *CharBuf,
36513655

36523656
ImageInfo->sections_found |= FOUND_IFD0;
36533657
/* First directory starts at offset 8. Offsets starts at 0. */
3654-
exif_process_IFD_in_JPEG(ImageInfo, CharBuf+offset_of_ifd, CharBuf, length/*-14*/, displacement, SECTION_IFD0);
3658+
exif_process_IFD_in_JPEG(ImageInfo, CharBuf+offset_of_ifd, CharBuf, length/*-14*/, displacement, SECTION_IFD0, 0);
36553659

36563660
#ifdef EXIF_DEBUG
36573661
exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Process TIFF in JPEG done");
860 KB
Loading
917 KB
Loading

ext/exif/tests/bug50660/bug50660.phpt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
Bug #50660 (exif_read_data(): Illegal IFD offset (works fine with other exif readers))
3+
--SKIPIF--
4+
<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?>
5+
--INI--
6+
output_handler=
7+
zlib.output_compression=0
8+
--FILE--
9+
<?php
10+
$infile = dirname(__FILE__).'/bug50660-1.jpg';
11+
var_dump(exif_read_data($infile) !== false);
12+
$infile = dirname(__FILE__).'/bug50660-2.jpg';
13+
var_dump(exif_read_data($infile) !== false);
14+
?>
15+
===DONE===
16+
--EXPECTF--
17+
bool(true)
18+
bool(true)
19+
===DONE===

0 commit comments

Comments
 (0)