@@ -69,7 +69,7 @@ PHP_MINFO_FUNCTION(exif)
6969 php_info_print_table_start ();
7070 php_info_print_table_row (2 , "EXIF Support" , "enabled" );
7171 php_info_print_table_row (2 , "Supported EXIF Version" , "0220" );
72- php_info_print_table_row (2 , "Supported filetypes" , "JPEG, TIFF" );
72+ php_info_print_table_row (2 , "Supported filetypes" , "JPEG, TIFF, HEIF, WebP " );
7373
7474 if (USE_MBSTRING ) {
7575 php_info_print_table_row (2 , "Multibyte decoding support using mbstring" , "enabled" );
@@ -4445,6 +4445,54 @@ static bool exif_scan_HEIF_header(image_info_type *ImageInfo, unsigned char *buf
44454445 return ret ;
44464446}
44474447
4448+ static bool exif_scan_WEBP_header (image_info_type * ImageInfo , size_t riff_size )
4449+ {
4450+ /* "Exif\0\0" identifier code */
4451+ static const uchar ExifHeader [] = {0x45 , 0x78 , 0x69 , 0x66 , 0x00 , 0x00 };
4452+ unsigned char chunk_header [8 ];
4453+ size_t offset = 12 ;
4454+ size_t riff_end = riff_size <= ImageInfo -> FileSize - 8 ? riff_size + 8 : ImageInfo -> FileSize ;
4455+
4456+ while (offset + 8 <= riff_end ) {
4457+ if ((php_stream_seek (ImageInfo -> infile , offset , SEEK_SET ) < 0 ) ||
4458+ (exif_read_from_stream_file_looped (ImageInfo -> infile , (char * )chunk_header , 8 ) != 8 )) {
4459+ return false;
4460+ }
4461+
4462+ size_t chunk_size = php_ifd_get32u (chunk_header + 4 , 0 );
4463+ size_t payload_offset = offset + 8 ;
4464+
4465+ if (chunk_size > riff_end - payload_offset ) {
4466+ return false;
4467+ }
4468+
4469+ if (!memcmp (chunk_header , "EXIF" , 4 )) {
4470+ size_t skip = 0 ;
4471+ bool ret = false;
4472+
4473+ if (chunk_size < 8 ) {
4474+ return false;
4475+ }
4476+
4477+ char * data = emalloc (chunk_size );
4478+ if (exif_read_from_stream_file_looped (ImageInfo -> infile , data , chunk_size ) == chunk_size ) {
4479+ if (chunk_size >= sizeof (ExifHeader ) + 8 && !memcmp (data , ExifHeader , sizeof (ExifHeader ))) {
4480+ skip = sizeof (ExifHeader );
4481+ }
4482+ exif_process_TIFF_in_JPEG (ImageInfo , data + skip , chunk_size - skip , payload_offset + skip );
4483+ ret = true;
4484+ }
4485+ efree (data );
4486+ return ret ;
4487+ }
4488+
4489+ /* RIFF chunks are word-aligned: an odd payload is followed by a pad byte. */
4490+ offset = payload_offset + chunk_size + (chunk_size & 1 );
4491+ }
4492+
4493+ return false;
4494+ }
4495+
44484496/* {{{ exif_scan_FILE_header
44494497 * Parse the marker stream until SOS or EOI is seen; */
44504498static bool exif_scan_FILE_header (image_info_type * ImageInfo )
@@ -4521,6 +4569,17 @@ static bool exif_scan_FILE_header(image_info_type *ImageInfo)
45214569 exif_error_docref (NULL EXIFERR_CC , ImageInfo , E_WARNING , "Invalid HEIF file ");
45224570 return false;
45234571 }
4572+ } else if ((ImageInfo -> FileSize >= 16 ) &&
4573+ (!memcmp (file_header , "RIFF" , 4 )) &&
4574+ (exif_read_from_stream_file_looped (ImageInfo -> infile , (char * )(file_header + 8 ), 4 ) == 4 ) &&
4575+ (!memcmp (file_header + 8 , "WEBP" , 4 ))) {
4576+ if (exif_scan_WEBP_header (ImageInfo , php_ifd_get32u (file_header + 4 , 0 ))) {
4577+ ImageInfo -> FileType = IMAGE_FILETYPE_WEBP ;
4578+ return true;
4579+ } else {
4580+ exif_error_docref (NULL EXIFERR_CC , ImageInfo , E_WARNING , "Invalid WebP file ");
4581+ return false;
4582+ }
45244583 } else {
45254584 exif_error_docref (NULL EXIFERR_CC , ImageInfo , E_WARNING , "File not supported ");
45264585 return false;
0 commit comments