mirror of
https://github.com/php/php-src.git
synced 2024-09-21 18:07:23 +00:00
Merge branch 'PHP-7.4'
* PHP-7.4: Make MAX_IFD_NESTING_LEVEL an actual nesting level
This commit is contained in:
commit
5f4b169be8
@ -62,7 +62,8 @@ typedef unsigned char uchar;
|
||||
|
||||
#define EFREE_IF(ptr) if (ptr) efree(ptr)
|
||||
|
||||
#define MAX_IFD_NESTING_LEVEL 200
|
||||
#define MAX_IFD_NESTING_LEVEL 10
|
||||
#define MAX_IFD_TAGS 1000
|
||||
|
||||
/* {{{ PHP_MINFO_FUNCTION */
|
||||
PHP_MINFO_FUNCTION(exif)
|
||||
@ -1975,6 +1976,7 @@ typedef struct {
|
||||
int read_thumbnail;
|
||||
int read_all;
|
||||
int ifd_nesting_level;
|
||||
int ifd_count;
|
||||
int num_errors;
|
||||
/* internal */
|
||||
file_section_list file;
|
||||
@ -2696,6 +2698,7 @@ static void exif_process_SOFn (uchar *Data, int marker, jpeg_sof_info *result)
|
||||
/* forward declarations */
|
||||
static bool exif_process_IFD_in_JPEG(image_info_type *ImageInfo, char *dir_start, const exif_offset_info *info, size_t displacement, int section_index, int tag);
|
||||
static bool exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, const exif_offset_info *info, size_t displacement, int section_index, int ReadNextIFD, tag_table_type tag_table);
|
||||
static bool exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offset, int section_index);
|
||||
|
||||
/* {{{ exif_get_markername
|
||||
Get name of marker */
|
||||
@ -3238,7 +3241,7 @@ static bool exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * val
|
||||
|
||||
/* {{{ exif_process_IFD_TAG
|
||||
* Process one of the nested IFDs directories. */
|
||||
static bool exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, const exif_offset_info *info, size_t displacement, int section_index, int ReadNextIFD, tag_table_type tag_table)
|
||||
static bool exif_process_IFD_TAG_impl(image_info_type *ImageInfo, char *dir_entry, const exif_offset_info *info, size_t displacement, int section_index, int ReadNextIFD, tag_table_type tag_table)
|
||||
{
|
||||
size_t length;
|
||||
unsigned int tag, format, components;
|
||||
@ -3251,13 +3254,6 @@ static bool exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, co
|
||||
int dump_free;
|
||||
#endif /* EXIF_DEBUG */
|
||||
|
||||
/* Protect against corrupt headers */
|
||||
if (ImageInfo->ifd_nesting_level > MAX_IFD_NESTING_LEVEL) {
|
||||
exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "corrupt EXIF header: maximum directory nesting level reached");
|
||||
return false;
|
||||
}
|
||||
ImageInfo->ifd_nesting_level++;
|
||||
|
||||
tag = php_ifd_get16u(dir_entry, ImageInfo->motorola_intel);
|
||||
format = php_ifd_get16u(dir_entry+2, ImageInfo->motorola_intel);
|
||||
components = php_ifd_get32u(dir_entry+4, ImageInfo->motorola_intel);
|
||||
@ -3568,6 +3564,24 @@ static bool exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, co
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static bool exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, const exif_offset_info *info, size_t displacement, int section_index, int ReadNextIFD, tag_table_type tag_table)
|
||||
{
|
||||
bool result;
|
||||
/* Protect against corrupt headers */
|
||||
if (ImageInfo->ifd_count++ > MAX_IFD_TAGS) {
|
||||
exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "corrupt EXIF header: maximum IFD tag count reached");
|
||||
return false;
|
||||
}
|
||||
if (ImageInfo->ifd_nesting_level > MAX_IFD_NESTING_LEVEL) {
|
||||
exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "corrupt EXIF header: maximum directory nesting level reached");
|
||||
return false;
|
||||
}
|
||||
ImageInfo->ifd_nesting_level++;
|
||||
result = exif_process_IFD_TAG_impl(ImageInfo, dir_entry, info, displacement, section_index, ReadNextIFD, tag_table);
|
||||
ImageInfo->ifd_nesting_level--;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* {{{ exif_process_IFD_in_JPEG
|
||||
* Process one of the nested IFDs directories. */
|
||||
static bool exif_process_IFD_in_JPEG(image_info_type *ImageInfo, char *dir_start, const exif_offset_info *info, size_t displacement, int section_index, int tag)
|
||||
@ -4008,7 +4022,7 @@ static bool exif_scan_thumbnail(image_info_type *ImageInfo)
|
||||
|
||||
/* {{{ exif_process_IFD_in_TIFF
|
||||
* Parse the TIFF header; */
|
||||
static bool exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offset, int section_index)
|
||||
static bool exif_process_IFD_in_TIFF_impl(image_info_type *ImageInfo, size_t dir_offset, int section_index)
|
||||
{
|
||||
int i, sn, num_entries, sub_section_index = 0;
|
||||
unsigned char *dir_entry;
|
||||
@ -4016,10 +4030,6 @@ static bool exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offs
|
||||
int entry_tag , entry_type;
|
||||
tag_table_type tag_table = exif_get_tag_table(section_index);
|
||||
|
||||
if (ImageInfo->ifd_nesting_level > MAX_IFD_NESTING_LEVEL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ImageInfo->FileSize >= 2 && ImageInfo->FileSize - 2 >= dir_offset) {
|
||||
sn = exif_file_sections_add(ImageInfo, M_PSEUDO, 2, NULL);
|
||||
#ifdef EXIF_DEBUG
|
||||
@ -4162,7 +4172,6 @@ static bool exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offs
|
||||
#ifdef EXIF_DEBUG
|
||||
exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Next IFD: %s @x%04X", exif_get_sectionname(sub_section_index), entry_offset);
|
||||
#endif
|
||||
ImageInfo->ifd_nesting_level++;
|
||||
exif_process_IFD_in_TIFF(ImageInfo, entry_offset, sub_section_index);
|
||||
if (section_index!=SECTION_THUMBNAIL && entry_tag==TAG_SUB_IFD) {
|
||||
if (ImageInfo->Thumbnail.filetype != IMAGE_FILETYPE_UNKNOWN
|
||||
@ -4209,7 +4218,6 @@ static bool exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offs
|
||||
#ifdef EXIF_DEBUG
|
||||
exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Read next IFD (THUMBNAIL) at x%04X", next_offset);
|
||||
#endif
|
||||
ImageInfo->ifd_nesting_level++;
|
||||
exif_process_IFD_in_TIFF(ImageInfo, next_offset, SECTION_THUMBNAIL);
|
||||
#ifdef EXIF_DEBUG
|
||||
exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "%s THUMBNAIL @0x%04X + 0x%04X", ImageInfo->Thumbnail.data ? "Ignore" : "Read", ImageInfo->Thumbnail.offset, ImageInfo->Thumbnail.size);
|
||||
@ -4246,6 +4254,21 @@ static bool exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offs
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static bool exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offset, int section_index)
|
||||
{
|
||||
bool result;
|
||||
if (ImageInfo->ifd_count++ > MAX_IFD_TAGS) {
|
||||
return false;
|
||||
}
|
||||
if (ImageInfo->ifd_nesting_level > MAX_IFD_NESTING_LEVEL) {
|
||||
return false;
|
||||
}
|
||||
ImageInfo->ifd_nesting_level++;
|
||||
result = exif_process_IFD_in_TIFF_impl(ImageInfo, dir_offset, section_index);
|
||||
ImageInfo->ifd_nesting_level--;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* {{{ exif_scan_FILE_header
|
||||
* Parse the marker stream until SOS or EOI is seen; */
|
||||
static bool exif_scan_FILE_header(image_info_type *ImageInfo)
|
||||
@ -4399,6 +4422,7 @@ static bool exif_read_from_impl(image_info_type *ImageInfo, php_stream *stream,
|
||||
|
||||
|
||||
ImageInfo->ifd_nesting_level = 0;
|
||||
ImageInfo->ifd_count = 0;
|
||||
ImageInfo->num_errors = 0;
|
||||
|
||||
/* Scan the headers */
|
||||
|
10
ext/exif/tests/nesting_level_oom.phpt
Normal file
10
ext/exif/tests/nesting_level_oom.phpt
Normal file
@ -0,0 +1,10 @@
|
||||
--TEST--
|
||||
Should not cause OOM
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
var_dump(@exif_read_data(__DIR__ . '/nesting_level_oom.tiff'));
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(false)
|
BIN
ext/exif/tests/nesting_level_oom.tiff
Normal file
BIN
ext/exif/tests/nesting_level_oom.tiff
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user