summaryrefslogtreecommitdiff
path: root/ext/exif/exif.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/exif/exif.c')
-rw-r--r--ext/exif/exif.c41
1 files changed, 31 insertions, 10 deletions
diff --git a/ext/exif/exif.c b/ext/exif/exif.c
index e8c622418a..9f951d78a3 100644
--- a/ext/exif/exif.c
+++ b/ext/exif/exif.c
@@ -2604,6 +2604,7 @@ static int exif_process_user_comment(image_info_type *ImageInfo, char **pszInfoP
*pszEncoding = NULL;
/* Copy the comment */
if (ByteCount>=8) {
+ const zend_encoding *from, *to;
if (!memcmp(szValuePtr, "UNICODE\0", 8)) {
*pszEncoding = estrdup((const char*)szValuePtr);
szValuePtr = szValuePtr+8;
@@ -2624,15 +2625,16 @@ static int exif_process_user_comment(image_info_type *ImageInfo, char **pszInfoP
} else {
decode = ImageInfo->decode_unicode_le;
}
+ to = zend_multibyte_fetch_encoding(ImageInfo->encode_unicode);
+ from = zend_multibyte_fetch_encoding(decode);
/* XXX this will fail again if encoding_converter returns on error something different than SIZE_MAX */
- if (zend_multibyte_encoding_converter(
+ if (!to || !from || zend_multibyte_encoding_converter(
(unsigned char**)pszInfoPtr,
&len,
(unsigned char*)szValuePtr,
ByteCount,
- zend_multibyte_fetch_encoding(ImageInfo->encode_unicode),
- zend_multibyte_fetch_encoding(decode)
- ) == (size_t)-1) {
+ to,
+ from) == (size_t)-1) {
len = exif_process_string_raw(pszInfoPtr, szValuePtr, ByteCount);
}
return len;
@@ -2646,14 +2648,15 @@ static int exif_process_user_comment(image_info_type *ImageInfo, char **pszInfoP
szValuePtr = szValuePtr+8;
ByteCount -= 8;
/* XXX this will fail again if encoding_converter returns on error something different than SIZE_MAX */
- if (zend_multibyte_encoding_converter(
+ to = zend_multibyte_fetch_encoding(ImageInfo->encode_jis);
+ from = zend_multibyte_fetch_encoding(ImageInfo->motorola_intel ? ImageInfo->decode_jis_be : ImageInfo->decode_jis_le);
+ if (!to || !from || zend_multibyte_encoding_converter(
(unsigned char**)pszInfoPtr,
&len,
(unsigned char*)szValuePtr,
ByteCount,
- zend_multibyte_fetch_encoding(ImageInfo->encode_jis),
- zend_multibyte_fetch_encoding(ImageInfo->motorola_intel ? ImageInfo->decode_jis_be : ImageInfo->decode_jis_le)
- ) == (size_t)-1) {
+ to,
+ from) == (size_t)-1) {
len = exif_process_string_raw(pszInfoPtr, szValuePtr, ByteCount);
}
return len;
@@ -2724,6 +2727,12 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu
break;
}
+ if (maker_note->offset >= value_len) {
+ /* Do not go past the value end */
+ exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "IFD data too short: 0x%04X offset 0x%04X", value_len, maker_note->offset);
+ return FALSE;
+ }
+
dir_start = value_ptr + maker_note->offset;
#ifdef EXIF_DEBUG
@@ -2752,10 +2761,19 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu
offset_base = value_ptr;
break;
case MN_OFFSET_GUESS:
+ if (maker_note->offset + 10 + 4 >= value_len) {
+ /* Can not read dir_start+10 since it's beyond value end */
+ exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "IFD data too short: 0x%04X", value_len);
+ return FALSE;
+ }
offset_diff = 2 + NumDirEntries*12 + 4 - php_ifd_get32u(dir_start+10, ImageInfo->motorola_intel);
#ifdef EXIF_DEBUG
exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Using automatic offset correction: 0x%04X", ((int)dir_start-(int)offset_base+maker_note->offset+displacement) + offset_diff);
#endif
+ if (offset_diff < 0 || offset_diff >= value_len ) {
+ exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "IFD data bad offset: 0x%04X length 0x%04X", offset_diff, value_len);
+ return FALSE;
+ }
offset_base = value_ptr + offset_diff;
break;
default:
@@ -2764,7 +2782,7 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu
}
if ((2+NumDirEntries*12) > value_len) {
- exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Illegal IFD size: 2 + x%04X*12 = x%04X > x%04X", NumDirEntries, 2+NumDirEntries*12, value_len);
+ exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Illegal IFD size: 2 + 0x%04X*12 = 0x%04X > 0x%04X", NumDirEntries, 2+NumDirEntries*12, value_len);
return FALSE;
}
@@ -3050,7 +3068,10 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
break;
case TAG_MAKER_NOTE:
- exif_process_IFD_in_MAKERNOTE(ImageInfo, value_ptr, byte_count, offset_base, IFDlength, displacement);
+ if (!exif_process_IFD_in_MAKERNOTE(ImageInfo, value_ptr, byte_count, offset_base, IFDlength, displacement)) {
+ EFREE_IF(outside);
+ return FALSE;
+ }
break;
case TAG_EXIF_IFD_POINTER: