Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

exif read : warnings and errors : Potentially invalid endianess, Illegal IFD size and Undefined index #9397

Closed
Ben29980 opened this issue Aug 20, 2022 · 15 comments

Comments

@Ben29980
Copy link

Hello community,
I read that on older php versions exif read function was not working properly on certain images.
I should have been patched with new php versions... But not fully...

On recent DJI images, I have a persistent uncapacity to correctly "read exif data" from image

Image example:
DJI_20220813101819_0001_W

here an example of errors I have:
php_exif_error

Please note that with other images, it works like a charm. And not problem for me to extract data.

Here is my code:
`//get the EXIF
$exif = exif_read_data($file, 'IFD0');
echo $exif===false ? "Aucun en-tête de donnés n'a été trouvé.
\n" : "L'image contient des en-têtes
\n";
$exif = exif_read_data($file);

//get the Hemisphere multiplier
$LatM = 1; 
$LongM = 1;
if($exif["GPSLatitudeRef"] == 'S')
{
$LatM = -1;
}
if($exif["GPSLongitudeRef"] == 'W')
{
$LongM = -1;
}

$alt      = explode('/', $exif["GPSAltitude"]);
$altitude = (isset($alt[1])) ? ($alt[0] / $alt[1]) : $alt[0];

//get the GPS data
$gps['LatDegree']=$exif["GPSLatitude"][0];
$gps['LatMinute']=$exif["GPSLatitude"][1];
$gps['LatgSeconds']=$exif["GPSLatitude"][2];
$gps['LongDegree']=$exif["GPSLongitude"][0];
$gps['LongMinute']=$exif["GPSLongitude"][1];
$gps['LongSeconds']=$exif["GPSLongitude"][2];`
@Girgias
Copy link
Member

Girgias commented Aug 20, 2022

What PHP version are you running? (also this is probably more a php-src issue then a doc issue)

@cmb69
Copy link
Contributor

cmb69 commented Aug 22, 2022

also this is probably more a php-src issue then a doc issue

Right. Transferring.

@cmb69 cmb69 transferred this issue from php/doc-en Aug 22, 2022
@cmb69
Copy link
Contributor

cmb69 commented Aug 22, 2022

The problem is that this image has a makernote with an uncommon (non-standard?) format which contains the DJI Info Tags. Since there is no special support for reading this, the reading fails early, and that causes quite some information to be missing from the exif_read_data() results.

I have not been able to find some normative information about this format, but the following work-around might be a start:

 ext/exif/exif.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/ext/exif/exif.c b/ext/exif/exif.c
index a6db8745b3..51545f74cc 100644
--- a/ext/exif/exif.c
+++ b/ext/exif/exif.c
@@ -3170,6 +3170,10 @@ static bool exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * val
 
 	dir_start = value_ptr + maker_note->offset;
 
+	if (!strcmp(maker_note->make, "DJI") && *dir_start == '[') {
+		return true;
+	}
+
 #ifdef EXIF_DEBUG
 	exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Process %s @x%04X + 0x%04X=%d: %s", exif_get_sectionname(section_index), (intptr_t)dir_start-(intptr_t)info->offset_base+maker_note->offset+displacement, value_len, value_len, exif_char_dump(value_ptr, value_len, (intptr_t)dir_start-(intptr_t)info->offset_base+maker_note->offset+displacement));
 #endif
That would yield:
array(70) {
  ["FileName"]=>
  string(10) "gh1760.jpg"
  ["FileDateTime"]=>
  int(1661168285)
  ["FileSize"]=>
  int(9142758)
  ["FileType"]=>
  int(2)
  ["MimeType"]=>
  string(10) "image/jpeg"
  ["SectionsFound"]=>
  string(51) "ANY_TAG, IFD0, THUMBNAIL, EXIF, GPS, INTEROP, WINXP"
  ["COMPUTED"]=>
  array(8) {
    ["html"]=>
    string(26) "width="4056" height="3040""
    ["Height"]=>
    int(3040)
    ["Width"]=>
    int(4056)
    ["IsColor"]=>
    int(1)
    ["ByteOrderMotorola"]=>
    int(0)
    ["ApertureFNumber"]=>
    string(5) "f/2.8"
    ["Thumbnail.FileType"]=>
    int(2)
    ["Thumbnail.MimeType"]=>
    string(10) "image/jpeg"
  }
  ["ImageDescription"]=>
  string(7) "default"
  ["Make"]=>
  string(3) "DJI"
  ["Model"]=>
  string(5) "ZH20T"
  ["Orientation"]=>
  int(1)
  ["XResolution"]=>
  string(4) "72/1"
  ["YResolution"]=>
  string(4) "72/1"
  ["ResolutionUnit"]=>
  int(2)
  ["Software"]=>
  string(11) "04.00.00.10"
  ["DateTime"]=>
  string(19) "2022:08:13 10:18:19"
  ["YCbCrPositioning"]=>
  int(2)
  ["Exif_IFD_Pointer"]=>
  int(260)
  ["GPS_IFD_Pointer"]=>
  int(710)
  ["Comments"]=>
  string(7) "0.9.142"
  ["Keywords"]=>
  string(6) "single"
  ["THUMBNAIL"]=>
  array(6) {
    ["Compression"]=>
    int(7)
    ["XResolution"]=>
    string(4) "72/1"
    ["YResolution"]=>
    string(4) "72/1"
    ["ResolutionUnit"]=>
    int(2)
    ["JPEGInterchangeFormat"]=>
    int(24962)
    ["JPEGInterchangeFormatLength"]=>
    int(11927)
  }
  ["ExposureTime"]=>
  string(5) "1/725"
  ["FNumber"]=>
  string(7) "280/100"
  ["ExposureProgram"]=>
  int(2)
  ["ISOSpeedRatings"]=>
  int(110)
  ["UndefinedTag:0x8830"]=>
  int(2)
  ["ExifVersion"]=>
  string(4) "0230"
  ["DateTimeOriginal"]=>
  string(19) "2022:08:13 10:18:19"
  ["DateTimeDigitized"]=>
  string(19) "2022:08:13 10:18:19"
  ["ComponentsConfiguration"]=>
  string(4) "���"
  ["ShutterSpeedValue"]=>
  string(11) "95018/10000"
  ["ApertureValue"]=>
  string(7) "297/100"
  ["ExposureBiasValue"]=>
  string(4) "0/10"
  ["MaxApertureValue"]=>
  string(7) "297/100"
  ["MeteringMode"]=>
  int(2)
  ["LightSource"]=>
  int(1)
  ["Flash"]=>
  int(0)
  ["FocalLength"]=>
  string(9) "4500/1000"
  ["MakerNote"]=>
  string(13) "[ae_dbg_info:"
  ["FlashPixVersion"]=>
  string(4) "0100"
  ["ColorSpace"]=>
  int(1)
  ["ExifImageWidth"]=>
  int(4056)
  ["ExifImageLength"]=>
  int(3040)
  ["InteroperabilityOffset"]=>
  int(824)
  ["FileSource"]=>
  string(1) "�"
  ["SceneType"]=>
  string(1) "�"
  ["ExposureMode"]=>
  int(0)
  ["WhiteBalance"]=>
  int(0)
  ["DigitalZoomRatio"]=>
  string(7) "100/100"
  ["FocalLengthIn35mmFilm"]=>
  int(24)
  ["SceneCaptureType"]=>
  int(0)
  ["GainControl"]=>
  int(0)
  ["Contrast"]=>
  int(0)
  ["Saturation"]=>
  int(0)
  ["Sharpness"]=>
  int(0)
  ["DeviceSettingDescription"]=>
  string(4) ""
  ["UndefinedTag:0xA431"]=>
  string(14) "1W9DK5T001EV6H"
  ["UndefinedTag:0xA432"]=>
  array(4) {
    [0]=>
    string(9) "4500/1000"
    [1]=>
    string(9) "4500/1000"
    [2]=>
    string(7) "280/100"
    [3]=>
    string(7) "280/100"
  }
  ["GPSVersion"]=>
  string(4) "��"
  ["GPSLatitudeRef"]=>
  string(1) "N"
  ["GPSLatitude"]=>
  array(3) {
    [0]=>
    string(4) "46/1"
    [1]=>
    string(3) "9/1"
    [2]=>
    string(12) "388800/10000"
  }
  ["GPSLongitudeRef"]=>
  string(1) "E"
  ["GPSLongitude"]=>
  array(3) {
    [0]=>
    string(3) "5/1"
    [1]=>
    string(4) "39/1"
    [2]=>
    string(12) "403541/10000"
  }
  ["GPSAltitudeRef"]=>
  string(1) ""
  ["GPSAltitude"]=>
  string(11) "760236/1000"
  ["GPSStatus"]=>
  string(1) "A"
  ["GPSMapDatum"]=>
  string(6) "WGS-84"
  ["InterOperabilityIndex"]=>
  string(3) "R98"
  ["InterOperabilityVersion"]=>
  string(4) "0100"
}

@Ben29980
Copy link
Author

What PHP version are you running? (also this is probably more a php-src issue then a doc issue)

My PHP version is 8.1.0.

The problem is that this image has a makernote with an uncommon (non-standard?) format which contains the DJI Info Tags. Since there is no special support for reading this, the reading fails early, and that causes quite some information to be missing from the exif_read_data() results.

I have not been able to find some normative information about this format, but the following work-around might be a start:

 ext/exif/exif.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/ext/exif/exif.c b/ext/exif/exif.c
index a6db8745b3..51545f74cc 100644
--- a/ext/exif/exif.c
+++ b/ext/exif/exif.c
@@ -3170,6 +3170,10 @@ static bool exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * val
 
 	dir_start = value_ptr + maker_note->offset;
 
+	if (!strcmp(maker_note->make, "DJI") && *dir_start == '[') {
+		return true;
+	}
+
 #ifdef EXIF_DEBUG
 	exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Process %s @x%04X + 0x%04X=%d: %s", exif_get_sectionname(section_index), (intptr_t)dir_start-(intptr_t)info->offset_base+maker_note->offset+displacement, value_len, value_len, exif_char_dump(value_ptr, value_len, (intptr_t)dir_start-(intptr_t)info->offset_base+maker_note->offset+displacement));
 #endif

That would yield:

Thanks @cmb69, do you think that native php exif read function could be updated ?
Or should I use a php exiftools library ?

@cmb69
Copy link
Contributor

cmb69 commented Aug 22, 2022

Completely failing to parse other EXIF data after parsing the maker note failed, is a bug, and should be fixed (not sure how; patch above is more like a PoC). Being able to parse DJI info tags is more like a feature request, though.

@Ben29980
Copy link
Author

Completely failing to parse other EXIF data after parsing the maker note failed, is a bug, and should be fixed (not sure how; patch above is more like a PoC). Being able to parse DJI info tags is more like a feature request, though.

Thanks @cmb69 , should I open a feature request ?

@cmb69
Copy link
Contributor

cmb69 commented Sep 19, 2022

should I open a feature request ?

Feel free to open a new ticket. However, someone needs to implement that. :)

@akkana
Copy link

akkana commented Apr 4, 2023

I'm not sure if I'm in the right issue, but I'm seeing the "Illegal IFD size" warning when I call exif_read_data() on https://shallowsky.com/images/annular-eclipse-2012/img_5405.jpg (among other images). It doesn't fail to parse the rest of the exif, it's just an annoying warning cluttering my server logs. exiftool shows the image's EXIF without any complaints. exiftool also doesn't show anything matching "dji", "maker" or "note". I'm not sure what PHP is complaining about or how to fix it since the warning isn't specific.

@nielsdos
Copy link
Member

nielsdos commented Apr 5, 2023

@akkana That looks like a different issue (the maker note is Canon). It might be because it's a Canon model specific maker note we don't yet parse, or because of a different reason. Can you please make a new bug report for that? Thank you!

@akkana
Copy link

akkana commented Apr 5, 2023

Done, issue #11020 with a small test case included. Sorry for spamming this issue.

@nielsdos nielsdos linked a pull request Apr 5, 2023 that will close this issue
nielsdos added a commit that referenced this issue Apr 5, 2023
* PHP-8.1:
  Fix GH-9397: exif read : warnings and errors : Potentially invalid endianess, Illegal IFD size and Undefined index
nielsdos added a commit that referenced this issue Apr 5, 2023
* PHP-8.2:
  Fix GH-9397: exif read : warnings and errors : Potentially invalid endianess, Illegal IFD size and Undefined index
@Ben29980
Copy link
Author

Hello dear,
Does anyone have news about this topic ?

By trying php 8.2, I still have error :
Illegal IFD size: 2 + 0x5B61*12 = 0x4488E > 0x5C75

Best

@Girgias
Copy link
Member

Girgias commented Aug 10, 2023

What patch version are you on? Because just saying PHP 8.2 is not sufficiant.

@Ben29980
Copy link
Author

8.2.0 sorry...

@Girgias
Copy link
Member

Girgias commented Aug 10, 2023

8.2.0 sorry...

Please update to the latest patch version

@Ben29980
Copy link
Author

Works fine ! Good job !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants
@akkana @cmb69 @nielsdos @Girgias @Ben29980 and others