From 3337d5d4dc68facb07c3c77f5975d7718f1f49af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ey=C3=BCp=20Can=20Akman?= Date: Fri, 26 Jun 2026 19:09:26 +0300 Subject: [PATCH] Fix GH-11020: spurious "Illegal IFD size" warning in exif_read_data() When an IFD is not followed by a 4-byte next-IFD offset, the EXIF block has no further IFD. Treat that as the end of the chain and return the parsed tags, instead of warning and discarding them. The bounds check from bug #72094 still applies, so the absent offset bytes are never read. --- NEWS | 4 ++++ ext/exif/exif.c | 10 ++++++++-- ext/exif/tests/bug72094.phpt | 2 -- ext/exif/tests/gh11020.jpg | Bin 0 -> 663 bytes ext/exif/tests/gh11020.phpt | 12 ++++++++++++ 5 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 ext/exif/tests/gh11020.jpg create mode 100644 ext/exif/tests/gh11020.phpt diff --git a/NEWS b/NEWS index d03a77b01d91..b48a0c7e6f80 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,10 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.4.24 +- Exif: + . Fixed bug GH-11020 (exif_read_data() emits a spurious "Illegal IFD size" + warning when an IFD is not followed by a next-IFD offset). (Eyüp Can Akman) + - Hash: . Fixed bug GH-18173 (ext/hash relies on implementation-defined malloc alignment). (iliaal) diff --git a/ext/exif/exif.c b/ext/exif/exif.c index 58e6d2801055..1b57377ffb89 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -3642,8 +3642,14 @@ static bool exif_process_IFD_in_JPEG(image_info_type *ImageInfo, char *dir_start * There are 2 IDFs, the second one holds the keys (0x0201 and 0x0202) to the thumbnail */ if (!exif_offset_info_contains(info, dir_start+2+NumDirEntries*12, 4)) { - exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Illegal IFD size"); - return false; + /* + * A TIFF/EXIF IFD ends with a 4-byte offset to the next IFD (IFD1 here, + * which links the thumbnail), or zero when there is none. Some files end + * the EXIF segment right after the entries and omit those 4 bytes. A + * missing offset is valid and just means there is no next IFD, so stop + * here instead of reporting the size as illegal. + */ + return true; } if (tag != TAG_EXIF_IFD_POINTER && tag != TAG_GPS_IFD_POINTER) { diff --git a/ext/exif/tests/bug72094.phpt b/ext/exif/tests/bug72094.phpt index c13a85f93f04..8fb3fa97c83d 100644 --- a/ext/exif/tests/bug72094.phpt +++ b/ext/exif/tests/bug72094.phpt @@ -47,8 +47,6 @@ Warning: exif_read_data(bug72094_3.jpg): Process tag(x3030=UndefinedTag): Illega Warning: exif_read_data(bug72094_3.jpg): Process tag(x3030=UndefinedTag): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d -Warning: exif_read_data(bug72094_3.jpg): Illegal IFD size in %s%ebug72094.php on line %d - Warning: exif_read_data(bug72094_3.jpg): File structure corrupted in %s%ebug72094.php on line %d Warning: exif_read_data(bug72094_3.jpg): Invalid JPEG file in %s%ebug72094.php on line %d diff --git a/ext/exif/tests/gh11020.jpg b/ext/exif/tests/gh11020.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1f978a7576136efe54818072f84dcf2bb52ab4e4 GIT binary patch literal 663 zcmex=BhhaM)G;tL zF)@)>x3sk|ve7d(F#;LF$jQmc!_6bX%PV1|D5GdZGWdUhL68IFC}u__1|~s9WI1EBlCfRTxrg_Vt+gOiIJs9>uA0}~@NGZPClD=P~NP<1U(o`FS>RY=j$ zkxe)-kzJ`!#HexNLJno8jR!@8E`CrkPAY2R|V^&07y2J$~}^+4C1KUw!=a`ODXD z-+%o41@ado12e>1KoYCJ1cClyVqsxsVF&q(k*OSrnFU!`6%E;h90S=C3x$=88aYIq zCNA7~kW<+>=!0ld(M2vX6_bamA3 +--EXPECT-- +bool(true) +int(1)