From 94b70f1ae065f10937c22b2d4b180ceade1ddeee Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Wed, 10 Jan 2024 21:57:50 +0000 Subject: [PATCH] Media: Fix handling of multibyte exif description metadata. The exif standards expect the UserComment field to be used as a substitute for ImageDescription if multibyte characters are needed. WordPress media only mapped the ImageDescription field and did not correctly handle descriptions with multibyte characters. Fix metadata saving to better handle media with multibyte characters in metadata and update unit tests. Props fotodrachen, antpb, joedolson, mikinc860, azaozz, nicolefurlan. Fixes #58082. git-svn-id: https://develop.svn.wordpress.org/trunk@57267 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/includes/image.php | 43 +++++++++++++++++++++++++----- tests/phpunit/tests/image/meta.php | 4 +-- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/wp-admin/includes/image.php b/src/wp-admin/includes/image.php index 2bdcc505e4..d60ec8508b 100644 --- a/src/wp-admin/includes/image.php +++ b/src/wp-admin/includes/image.php @@ -863,22 +863,51 @@ function wp_read_image_metadata( $file ) { $exif = array(); } + $exif_description = ''; + $exif_usercomment = ''; if ( ! empty( $exif['ImageDescription'] ) ) { - mbstring_binary_safe_encoding(); - $description_length = strlen( $exif['ImageDescription'] ); - reset_mbstring_encoding(); + $exif_description = trim( $exif['ImageDescription'] ); + } + if ( ! empty( $exif['COMPUTED']['UserComment'] ) ) { + $exif_usercomment = trim( $exif['COMPUTED']['UserComment'] ); + } + + if ( $exif_description ) { + mbstring_binary_safe_encoding(); + $description_length = strlen( $exif_description ); + reset_mbstring_encoding(); if ( empty( $meta['title'] ) && $description_length < 80 ) { // Assume the title is stored in ImageDescription. - $meta['title'] = trim( $exif['ImageDescription'] ); + $meta['title'] = $exif_description; } - if ( empty( $meta['caption'] ) && ! empty( $exif['COMPUTED']['UserComment'] ) ) { - $meta['caption'] = trim( $exif['COMPUTED']['UserComment'] ); + // If both user comments and description are present. + if ( empty( $meta['caption'] ) && $exif_description && $exif_usercomment ) { + if ( ! empty( $meta['title'] ) && $exif_description === $meta['title'] ) { + $caption = $exif_usercomment; + } else { + if ( $exif_description === $exif_usercomment ) { + $caption = $exif_description; + } else { + $caption = trim( $exif_description . ' ' . $exif_usercomment ); + } + } + $meta['caption'] = $caption; + } + + if ( empty( $meta['caption'] ) && $exif_usercomment ) { + $meta['caption'] = $exif_usercomment; } if ( empty( $meta['caption'] ) ) { - $meta['caption'] = trim( $exif['ImageDescription'] ); + $meta['caption'] = $exif_description; + } + } elseif ( empty( $meta['caption'] ) && $exif_usercomment ) { + $meta['caption'] = $exif_usercomment; + $description_length = strlen( $exif_usercomment ); + if ( empty( $meta['title'] ) && $description_length < 80 ) { + $meta['title'] = trim( $exif_usercomment ); } } elseif ( empty( $meta['caption'] ) && ! empty( $exif['Comments'] ) ) { $meta['caption'] = trim( $exif['Comments'] ); diff --git a/tests/phpunit/tests/image/meta.php b/tests/phpunit/tests/image/meta.php index b362cf1f20..2a65dee64c 100644 --- a/tests/phpunit/tests/image/meta.php +++ b/tests/phpunit/tests/image/meta.php @@ -51,13 +51,13 @@ class Tests_Image_Meta extends WP_UnitTestCase { $this->assertSame( '0', $out['aperture'], 'Aperture value not the same' ); $this->assertSame( '', $out['credit'], 'Credit value not the same' ); $this->assertSame( 'NIKON D70', $out['camera'], 'Camera value not the same' ); - $this->assertSame( '', $out['caption'], 'Caption value not the same' ); + $this->assertSame( 'Copyright Alex Shiels', $out['caption'], 'Caption value not the same' ); $this->assertEquals( strtotime( '2007-06-17 21:18:00' ), $out['created_timestamp'], 'Timestamp value not equivalent' ); $this->assertSame( '', $out['copyright'], 'Copyright value not the same' ); $this->assertEquals( 0, $out['focal_length'], 'Focal length value not equivalent' ); $this->assertEquals( 0, $out['iso'], 'Iso value not equivalent' ); // Interesting - a Nikon bug? $this->assertEquals( 1 / 500, $out['shutter_speed'], 'Shutter speed value not equivalent' ); - $this->assertSame( '', $out['title'], 'Title value not the same' ); + $this->assertSame( 'Copyright Alex Shiels', $out['title'], 'Title value not the same' ); // $this->assertSame( array( 'Flowers' ), $out['keywords'] ); }