@@ -66,7 +66,8 @@ typedef unsigned char uchar;
66
66
67
67
#define EFREE_IF (ptr ) if (ptr) efree(ptr)
68
68
69
- #define MAX_IFD_NESTING_LEVEL 200
69
+ #define MAX_IFD_NESTING_LEVEL 10
70
+ #define MAX_IFD_TAGS 1000
70
71
71
72
/* {{{ arginfo */
72
73
ZEND_BEGIN_ARG_INFO (arginfo_exif_tagname , 0 )
@@ -1940,6 +1941,7 @@ typedef struct {
1940
1941
int read_thumbnail ;
1941
1942
int read_all ;
1942
1943
int ifd_nesting_level ;
1944
+ int ifd_count ;
1943
1945
/* internal */
1944
1946
file_section_list file ;
1945
1947
} image_info_type ;
@@ -2674,6 +2676,7 @@ static void exif_process_SOFn (uchar *Data, int marker, jpeg_sof_info *result)
2674
2676
/* forward declarations */
2675
2677
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 );
2676
2678
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 );
2679
+ static int exif_process_IFD_in_TIFF (image_info_type * ImageInfo , size_t dir_offset , int section_index );
2677
2680
2678
2681
/* {{{ exif_get_markername
2679
2682
Get name of marker */
@@ -3246,7 +3249,7 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu
3246
3249
3247
3250
/* {{{ exif_process_IFD_TAG
3248
3251
* Process one of the nested IFDs directories. */
3249
- 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 )
3252
+ 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 )
3250
3253
{
3251
3254
size_t length ;
3252
3255
unsigned int tag , format , components ;
@@ -3259,13 +3262,6 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
3259
3262
int dump_free ;
3260
3263
#endif /* EXIF_DEBUG */
3261
3264
3262
- /* Protect against corrupt headers */
3263
- if (ImageInfo -> ifd_nesting_level > MAX_IFD_NESTING_LEVEL ) {
3264
- exif_error_docref ("exif_read_data#error_ifd" EXIFERR_CC , ImageInfo , E_WARNING , "corrupt EXIF header: maximum directory nesting level reached" );
3265
- return FALSE;
3266
- }
3267
- ImageInfo -> ifd_nesting_level ++ ;
3268
-
3269
3265
tag = php_ifd_get16u (dir_entry , ImageInfo -> motorola_intel );
3270
3266
format = php_ifd_get16u (dir_entry + 2 , ImageInfo -> motorola_intel );
3271
3267
components = php_ifd_get32u (dir_entry + 4 , ImageInfo -> motorola_intel );
@@ -3585,6 +3581,24 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
3585
3581
}
3586
3582
/* }}} */
3587
3583
3584
+ 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 )
3585
+ {
3586
+ int result ;
3587
+ /* Protect against corrupt headers */
3588
+ if (ImageInfo -> ifd_count ++ > MAX_IFD_TAGS ) {
3589
+ exif_error_docref ("exif_read_data#error_ifd" EXIFERR_CC , ImageInfo , E_WARNING , "corrupt EXIF header: maximum IFD tag count reached" );
3590
+ return FALSE;
3591
+ }
3592
+ if (ImageInfo -> ifd_nesting_level > MAX_IFD_NESTING_LEVEL ) {
3593
+ exif_error_docref ("exif_read_data#error_ifd" EXIFERR_CC , ImageInfo , E_WARNING , "corrupt EXIF header: maximum directory nesting level reached" );
3594
+ return FALSE;
3595
+ }
3596
+ ImageInfo -> ifd_nesting_level ++ ;
3597
+ result = exif_process_IFD_TAG_impl (ImageInfo , dir_entry , offset_base , IFDlength , displacement , section_index , ReadNextIFD , tag_table );
3598
+ ImageInfo -> ifd_nesting_level -- ;
3599
+ return result ;
3600
+ }
3601
+
3588
3602
/* {{{ exif_process_IFD_in_JPEG
3589
3603
* Process one of the nested IFDs directories. */
3590
3604
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 )
@@ -4018,7 +4032,7 @@ static int exif_scan_thumbnail(image_info_type *ImageInfo)
4018
4032
4019
4033
/* {{{ exif_process_IFD_in_TIFF
4020
4034
* Parse the TIFF header; */
4021
- static int exif_process_IFD_in_TIFF (image_info_type * ImageInfo , size_t dir_offset , int section_index )
4035
+ static int exif_process_IFD_in_TIFF_impl (image_info_type * ImageInfo , size_t dir_offset , int section_index )
4022
4036
{
4023
4037
int i , sn , num_entries , sub_section_index = 0 ;
4024
4038
unsigned char * dir_entry ;
@@ -4027,10 +4041,6 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse
4027
4041
int entry_tag , entry_type ;
4028
4042
tag_table_type tag_table = exif_get_tag_table (section_index );
4029
4043
4030
- if (ImageInfo -> ifd_nesting_level > MAX_IFD_NESTING_LEVEL ) {
4031
- return FALSE;
4032
- }
4033
-
4034
4044
if (ImageInfo -> FileSize >= 2 && ImageInfo -> FileSize - 2 >= dir_offset ) {
4035
4045
sn = exif_file_sections_add (ImageInfo , M_PSEUDO , 2 , NULL );
4036
4046
#ifdef EXIF_DEBUG
@@ -4174,7 +4184,6 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse
4174
4184
#ifdef EXIF_DEBUG
4175
4185
exif_error_docref (NULL EXIFERR_CC , ImageInfo , E_NOTICE , "Next IFD: %s @x%04X" , exif_get_sectionname (sub_section_index ), entry_offset );
4176
4186
#endif
4177
- ImageInfo -> ifd_nesting_level ++ ;
4178
4187
exif_process_IFD_in_TIFF (ImageInfo , entry_offset , sub_section_index );
4179
4188
if (section_index != SECTION_THUMBNAIL && entry_tag == TAG_SUB_IFD ) {
4180
4189
if (ImageInfo -> Thumbnail .filetype != IMAGE_FILETYPE_UNKNOWN
@@ -4218,7 +4227,6 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse
4218
4227
#ifdef EXIF_DEBUG
4219
4228
exif_error_docref (NULL EXIFERR_CC , ImageInfo , E_NOTICE , "Read next IFD (THUMBNAIL) at x%04X" , next_offset );
4220
4229
#endif
4221
- ImageInfo -> ifd_nesting_level ++ ;
4222
4230
exif_process_IFD_in_TIFF (ImageInfo , next_offset , SECTION_THUMBNAIL );
4223
4231
#ifdef EXIF_DEBUG
4224
4232
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 );
@@ -4255,6 +4263,21 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse
4255
4263
}
4256
4264
/* }}} */
4257
4265
4266
+ static int exif_process_IFD_in_TIFF (image_info_type * ImageInfo , size_t dir_offset , int section_index )
4267
+ {
4268
+ int result ;
4269
+ if (ImageInfo -> ifd_count ++ > MAX_IFD_TAGS ) {
4270
+ return FALSE;
4271
+ }
4272
+ if (ImageInfo -> ifd_nesting_level > MAX_IFD_NESTING_LEVEL ) {
4273
+ return FALSE;
4274
+ }
4275
+ ImageInfo -> ifd_nesting_level ++ ;
4276
+ result = exif_process_IFD_in_TIFF_impl (ImageInfo , dir_offset , section_index );
4277
+ ImageInfo -> ifd_nesting_level -- ;
4278
+ return result ;
4279
+ }
4280
+
4258
4281
/* {{{ exif_scan_FILE_header
4259
4282
* Parse the marker stream until SOS or EOI is seen; */
4260
4283
static int exif_scan_FILE_header (image_info_type * ImageInfo )
@@ -4410,6 +4433,7 @@ static int exif_read_from_impl(image_info_type *ImageInfo, php_stream *stream, i
4410
4433
4411
4434
4412
4435
ImageInfo -> ifd_nesting_level = 0 ;
4436
+ ImageInfo -> ifd_count = 0 ;
4413
4437
4414
4438
/* Scan the headers */
4415
4439
ret = exif_scan_FILE_header (ImageInfo );
0 commit comments