summaryrefslogtreecommitdiff
path: root/ext/exif
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-08-11 16:29:01 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-08-11 16:29:01 +0200
commit8694eb14f437cedb0b1b48be95862272fb818aeb (patch)
tree213c6a7f96306cb4c7617cd13d92313c18b5646f /ext/exif
parente25aab64268adb4e233737c274b195e1662f7211 (diff)
parent5c5508698d7c554065b4b36cbb73c6e8a9922d05 (diff)
downloadphp-git-8694eb14f437cedb0b1b48be95862272fb818aeb.tar.gz
Merge branch 'PHP-7.4'
* PHP-7.4: Fix bug #75785 by attempt switching endianness on Maker's Note
Diffstat (limited to 'ext/exif')
-rw-r--r--ext/exif/exif.c26
-rw-r--r--ext/exif/tests/bug75785/P1000506.JPGbin0 -> 35516 bytes
-rw-r--r--ext/exif/tests/bug75785/bug75785.phpt17
3 files changed, 34 insertions, 9 deletions
diff --git a/ext/exif/exif.c b/ext/exif/exif.c
index e89d74d9e9..5daa9c95b0 100644
--- a/ext/exif/exif.c
+++ b/ext/exif/exif.c
@@ -62,7 +62,7 @@ typedef unsigned char uchar;
#define EFREE_IF(ptr) if (ptr) efree(ptr)
-#define MAX_IFD_NESTING_LEVEL 150
+#define MAX_IFD_NESTING_LEVEL 200
/* {{{ PHP_MINFO_FUNCTION */
PHP_MINFO_FUNCTION(exif)
@@ -3185,14 +3185,12 @@ static bool exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * val
NumDirEntries = php_ifd_get16u(dir_start, ImageInfo->motorola_intel);
- switch (maker_note->offset_mode) {
- case MN_OFFSET_MAKER:
- exif_offset_info_init(&new_info, value_ptr, value_ptr, value_len);
- info = &new_info;
- break;
- default:
- case MN_OFFSET_NORMAL:
- break;
+ /* It can be that motorola_intel is wrongly mapped, let's try inverting it */
+ if ((2+NumDirEntries*12) > value_len) {
+ exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Potentially invalid endianess, trying again with different endianness before imminent failure.");
+
+ ImageInfo->motorola_intel = ImageInfo->motorola_intel == 0 ? 1 : 0;
+ NumDirEntries = php_ifd_get16u(dir_start, ImageInfo->motorola_intel);
}
if ((2+NumDirEntries*12) > value_len) {
@@ -3204,6 +3202,16 @@ static bool exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * val
return false;
}
+ switch (maker_note->offset_mode) {
+ case MN_OFFSET_MAKER:
+ exif_offset_info_init(&new_info, value_ptr, value_ptr, value_len);
+ info = &new_info;
+ break;
+ default:
+ case MN_OFFSET_NORMAL:
+ break;
+ }
+
for (de=0;de<NumDirEntries;de++) {
size_t offset = 2 + 12 * de;
if (!exif_process_IFD_TAG(ImageInfo, dir_start + offset,
diff --git a/ext/exif/tests/bug75785/P1000506.JPG b/ext/exif/tests/bug75785/P1000506.JPG
new file mode 100644
index 0000000000..3c74b4eee3
--- /dev/null
+++ b/ext/exif/tests/bug75785/P1000506.JPG
Binary files differ
diff --git a/ext/exif/tests/bug75785/bug75785.phpt b/ext/exif/tests/bug75785/bug75785.phpt
new file mode 100644
index 0000000000..b9f6551185
--- /dev/null
+++ b/ext/exif/tests/bug75785/bug75785.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Bug #75785 fix corrupt EXIF header issues; Related to mixed endianness. (Thank you @Richard Matzinger for providing the test photo)
+--SKIPIF--
+<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?>
+--FILE--
+<?php
+$mixedEndiannessFile = dirname(__FILE__).'/P1000506.JPG';
+$tags = exif_read_data($mixedEndiannessFile, 'EXIF', true, false);
+
+echo $tags['GPS']['GPSLatitude'][0] . PHP_EOL;
+echo $tags['GPS']['GPSLongitude'][0] . PHP_EOL;
+?>
+===DONE===
+--EXPECTF--
+38/1
+122/1
+===DONE===