mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3: Make MAX_IFD_NESTING_LEVEL an actual nesting level
This commit is contained in:
commit
c45985d266
3 changed files with 50 additions and 16 deletions
|
@ -64,7 +64,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
|
||||
|
||||
/* {{{ arginfo */
|
||||
ZEND_BEGIN_ARG_INFO(arginfo_exif_tagname, 0)
|
||||
|
@ -2022,6 +2023,7 @@ typedef struct {
|
|||
int read_thumbnail;
|
||||
int read_all;
|
||||
int ifd_nesting_level;
|
||||
int ifd_count;
|
||||
int num_errors;
|
||||
/* internal */
|
||||
file_section_list file;
|
||||
|
@ -2712,6 +2714,7 @@ static void exif_process_SOFn (uchar *Data, int marker, jpeg_sof_info *result)
|
|||
/* forward declarations */
|
||||
static int exif_process_IFD_in_JPEG(image_info_type *ImageInfo, char *dir_start, char *offset_base, size_t IFDlength, size_t displacement, int section_index, int tag);
|
||||
static int exif_process_IFD_TAG( image_info_type *ImageInfo, char *dir_entry, char *offset_base, size_t IFDlength, size_t displacement, int section_index, int ReadNextIFD, tag_table_type tag_table);
|
||||
static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offset, int section_index);
|
||||
|
||||
/* {{{ exif_get_markername
|
||||
Get name of marker */
|
||||
|
@ -3283,7 +3286,7 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu
|
|||
|
||||
/* {{{ exif_process_IFD_TAG
|
||||
* Process one of the nested IFDs directories. */
|
||||
static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, char *offset_base, size_t IFDlength, size_t displacement, int section_index, int ReadNextIFD, tag_table_type tag_table)
|
||||
static int exif_process_IFD_TAG_impl(image_info_type *ImageInfo, char *dir_entry, char *offset_base, size_t IFDlength, size_t displacement, int section_index, int ReadNextIFD, tag_table_type tag_table)
|
||||
{
|
||||
size_t length;
|
||||
unsigned int tag, format, components;
|
||||
|
@ -3296,13 +3299,6 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
|
|||
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);
|
||||
|
@ -3622,6 +3618,24 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, char *offset_base, size_t IFDlength, size_t displacement, int section_index, int ReadNextIFD, tag_table_type tag_table)
|
||||
{
|
||||
int 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, offset_base, IFDlength, 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 int exif_process_IFD_in_JPEG(image_info_type *ImageInfo, char *dir_start, char *offset_base, size_t IFDlength, size_t displacement, int section_index, int tag)
|
||||
|
@ -4055,7 +4069,7 @@ static int exif_scan_thumbnail(image_info_type *ImageInfo)
|
|||
|
||||
/* {{{ exif_process_IFD_in_TIFF
|
||||
* Parse the TIFF header; */
|
||||
static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offset, int section_index)
|
||||
static int 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;
|
||||
|
@ -4063,10 +4077,6 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse
|
|||
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
|
||||
|
@ -4210,7 +4220,6 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse
|
|||
#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
|
||||
|
@ -4254,7 +4263,6 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse
|
|||
#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);
|
||||
|
@ -4291,6 +4299,21 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offset, int section_index)
|
||||
{
|
||||
int 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 int exif_scan_FILE_header(image_info_type *ImageInfo)
|
||||
|
@ -4446,6 +4469,7 @@ static int exif_read_from_impl(image_info_type *ImageInfo, php_stream *stream, i
|
|||
|
||||
|
||||
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…
Add table
Add a link
Reference in a new issue