diff options
author | Stanislav Malyshev <stas@php.net> | 2016-07-19 01:44:14 -0700 |
---|---|---|
committer | Stanislav Malyshev <stas@php.net> | 2016-07-19 01:44:14 -0700 |
commit | 70d6ce336847b9acf2d8069075c14af74eda4c6d (patch) | |
tree | 3f1a684c7d093328aa74db9d934efff4a763866f /ext/exif/exif.c | |
parent | 5c90f9b9cdf61ff285aa902cf368ecd184bafd17 (diff) | |
parent | b00f8f2a5bae651d6375ca34c676963f1f25ee5a (diff) | |
download | php-git-70d6ce336847b9acf2d8069075c14af74eda4c6d.tar.gz |
Merge branch 'PHP-7.0'
* PHP-7.0: (27 commits)
fix #72519, possible OOB using imagegif
fix #72512, invalid read or write for palette image when invalid transparent index is used
Apparently some envs miss SIZE_MAX
Fix tests
Fix bug #72618: NULL Pointer Dereference in exif_process_user_comment
Partial fix for bug #72613 - do not allow reading past error read
Partial fix for bug #72613 - do not treat negative returns from bz2 as size_t
Fix bug #72606: heap-buffer-overflow (write) simplestring_addn simplestring.c
Fix for bug #72558, Integer overflow error within _gdContributionsAlloc()
Fix bug #72603: Out of bound read in exif_process_IFD_in_MAKERNOTE
update NEWS
Fixed bug #72570 Segmentation fault when binding parameters on a query without placeholders
Fix bug #72562 - destroy var_hash properly
Fix bug #72551 and bug #72552 - check before converting size_t->int
Fix bug #72541 - size_t overflow lead to heap corruption
Fix bug #72533 (locale_accept_from_http out-of-bounds access)
Fix fir bug #72520
Fix for bug #72513
Fix for bug #72513
CS fix and comments with bug ID
...
Conflicts:
ext/standard/basic_functions.c
Diffstat (limited to 'ext/exif/exif.c')
-rw-r--r-- | ext/exif/exif.c | 41 |
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: |