@@ -64,7 +64,8 @@ typedef unsigned char uchar;
64
64
65
65
#define EFREE_IF (ptr ) if (ptr) efree(ptr)
66
66
67
- #define MAX_IFD_NESTING_LEVEL 200
67
+ #define MAX_IFD_NESTING_LEVEL 10
68
+ #define MAX_IFD_TAGS 1000
68
69
69
70
/* {{{ arginfo */
70
71
ZEND_BEGIN_ARG_INFO (arginfo_exif_tagname , 0 )
@@ -2022,6 +2023,7 @@ typedef struct {
2022
2023
int read_thumbnail ;
2023
2024
int read_all ;
2024
2025
int ifd_nesting_level ;
2026
+ int ifd_count ;
2025
2027
int num_errors ;
2026
2028
/* internal */
2027
2029
file_section_list file ;
@@ -2712,6 +2714,7 @@ static void exif_process_SOFn (uchar *Data, int marker, jpeg_sof_info *result)
2712
2714
/* forward declarations */
2713
2715
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 );
2714
2716
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 );
2717
+ static int exif_process_IFD_in_TIFF (image_info_type * ImageInfo , size_t dir_offset , int section_index );
2715
2718
2716
2719
/* {{{ exif_get_markername
2717
2720
Get name of marker */
@@ -3283,7 +3286,7 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu
3283
3286
3284
3287
/* {{{ exif_process_IFD_TAG
3285
3288
* Process one of the nested IFDs directories. */
3286
- 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 )
3289
+ 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 )
3287
3290
{
3288
3291
size_t length ;
3289
3292
unsigned int tag , format , components ;
@@ -3296,13 +3299,6 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
3296
3299
int dump_free ;
3297
3300
#endif /* EXIF_DEBUG */
3298
3301
3299
- /* Protect against corrupt headers */
3300
- if (ImageInfo -> ifd_nesting_level > MAX_IFD_NESTING_LEVEL ) {
3301
- exif_error_docref ("exif_read_data#error_ifd" EXIFERR_CC , ImageInfo , E_WARNING , "corrupt EXIF header: maximum directory nesting level reached" );
3302
- return FALSE;
3303
- }
3304
- ImageInfo -> ifd_nesting_level ++ ;
3305
-
3306
3302
tag = php_ifd_get16u (dir_entry , ImageInfo -> motorola_intel );
3307
3303
format = php_ifd_get16u (dir_entry + 2 , ImageInfo -> motorola_intel );
3308
3304
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
3622
3618
}
3623
3619
/* }}} */
3624
3620
3621
+ 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 )
3622
+ {
3623
+ int result ;
3624
+ /* Protect against corrupt headers */
3625
+ if (ImageInfo -> ifd_count ++ > MAX_IFD_TAGS ) {
3626
+ exif_error_docref ("exif_read_data#error_ifd" EXIFERR_CC , ImageInfo , E_WARNING , "corrupt EXIF header: maximum IFD tag count reached" );
3627
+ return FALSE;
3628
+ }
3629
+ if (ImageInfo -> ifd_nesting_level > MAX_IFD_NESTING_LEVEL ) {
3630
+ exif_error_docref ("exif_read_data#error_ifd" EXIFERR_CC , ImageInfo , E_WARNING , "corrupt EXIF header: maximum directory nesting level reached" );
3631
+ return FALSE;
3632
+ }
3633
+ ImageInfo -> ifd_nesting_level ++ ;
3634
+ result = exif_process_IFD_TAG_impl (ImageInfo , dir_entry , offset_base , IFDlength , displacement , section_index , ReadNextIFD , tag_table );
3635
+ ImageInfo -> ifd_nesting_level -- ;
3636
+ return result ;
3637
+ }
3638
+
3625
3639
/* {{{ exif_process_IFD_in_JPEG
3626
3640
* Process one of the nested IFDs directories. */
3627
3641
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,18 +4069,14 @@ static int exif_scan_thumbnail(image_info_type *ImageInfo)
4055
4069
4056
4070
/* {{{ exif_process_IFD_in_TIFF
4057
4071
* Parse the TIFF header; */
4058
- static int exif_process_IFD_in_TIFF (image_info_type * ImageInfo , size_t dir_offset , int section_index )
4072
+ static int exif_process_IFD_in_TIFF_impl (image_info_type * ImageInfo , size_t dir_offset , int section_index )
4059
4073
{
4060
4074
int i , sn , num_entries , sub_section_index = 0 ;
4061
4075
unsigned char * dir_entry ;
4062
4076
size_t ifd_size , dir_size , entry_offset , next_offset , entry_length , entry_value = 0 , fgot ;
4063
4077
int entry_tag , entry_type ;
4064
4078
tag_table_type tag_table = exif_get_tag_table (section_index );
4065
4079
4066
- if (ImageInfo -> ifd_nesting_level > MAX_IFD_NESTING_LEVEL ) {
4067
- return FALSE;
4068
- }
4069
-
4070
4080
if (ImageInfo -> FileSize >= 2 && ImageInfo -> FileSize - 2 >= dir_offset ) {
4071
4081
sn = exif_file_sections_add (ImageInfo , M_PSEUDO , 2 , NULL );
4072
4082
#ifdef EXIF_DEBUG
@@ -4210,7 +4220,6 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse
4210
4220
#ifdef EXIF_DEBUG
4211
4221
exif_error_docref (NULL EXIFERR_CC , ImageInfo , E_NOTICE , "Next IFD: %s @x%04X" , exif_get_sectionname (sub_section_index ), entry_offset );
4212
4222
#endif
4213
- ImageInfo -> ifd_nesting_level ++ ;
4214
4223
exif_process_IFD_in_TIFF (ImageInfo , entry_offset , sub_section_index );
4215
4224
if (section_index != SECTION_THUMBNAIL && entry_tag == TAG_SUB_IFD ) {
4216
4225
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
4254
4263
#ifdef EXIF_DEBUG
4255
4264
exif_error_docref (NULL EXIFERR_CC , ImageInfo , E_NOTICE , "Read next IFD (THUMBNAIL) at x%04X" , next_offset );
4256
4265
#endif
4257
- ImageInfo -> ifd_nesting_level ++ ;
4258
4266
exif_process_IFD_in_TIFF (ImageInfo , next_offset , SECTION_THUMBNAIL );
4259
4267
#ifdef EXIF_DEBUG
4260
4268
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
4291
4299
}
4292
4300
/* }}} */
4293
4301
4302
+ static int exif_process_IFD_in_TIFF (image_info_type * ImageInfo , size_t dir_offset , int section_index )
4303
+ {
4304
+ int result ;
4305
+ if (ImageInfo -> ifd_count ++ > MAX_IFD_TAGS ) {
4306
+ return FALSE;
4307
+ }
4308
+ if (ImageInfo -> ifd_nesting_level > MAX_IFD_NESTING_LEVEL ) {
4309
+ return FALSE;
4310
+ }
4311
+ ImageInfo -> ifd_nesting_level ++ ;
4312
+ result = exif_process_IFD_in_TIFF_impl (ImageInfo , dir_offset , section_index );
4313
+ ImageInfo -> ifd_nesting_level -- ;
4314
+ return result ;
4315
+ }
4316
+
4294
4317
/* {{{ exif_scan_FILE_header
4295
4318
* Parse the marker stream until SOS or EOI is seen; */
4296
4319
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
4446
4469
4447
4470
4448
4471
ImageInfo -> ifd_nesting_level = 0 ;
4472
+ ImageInfo -> ifd_count = 0 ;
4449
4473
ImageInfo -> num_errors = 0 ;
4450
4474
4451
4475
/* Scan the headers */
0 commit comments