Make WordPress Core

Opened 4 weeks ago

Closed 4 weeks ago

#64849 closed defect (bug) (fixed)

Media: wp_get_image_alttext() incorrectly treats strpos() position 0 as "not found"

Reported by: suhan2411's profile suhan2411 Owned by: joedolson's profile joedolson
Milestone: 7.0 Priority: normal
Severity: normal Version: trunk
Component: Media Keywords: has-patch commit
Focuses: Cc:

Description

The wp_get_image_alttext() function in src/wp-admin/includes/image.php
checks for XMP metadata using strpos():

$xmp_start = strpos( $img_contents, '<x:xmpmeta' );
$xmp_end   = strpos( $img_contents, '</x:xmpmeta>' );

if ( ! $xmp_start || ! $xmp_end ) {
    return $alt_text;
}

This logic incorrectly treats a match at position 0 as "not found".

In PHP, strpos() returns:

0     → match found at position 0
false → no match

Because the code uses ! $xmp_start, a valid match at position 0 is treated as false, and the function returns an empty alt text.

As a result, valid XMP metadata may be ignored when it appears at the beginning of the file contents.

Additionally, file_get_contents() may return false on failure.

The current implementation passes that value directly to strpos(), which can trigger PHP warnings or errors.

Both issues can be resolved by using strict comparisons for strpos() and adding a safety check for file_get_contents() failure.

Change History (9)

This ticket was mentioned in PR #11237 on WordPress/wordpress-develop by @suhan2411.


4 weeks ago
#1

Fixes https://core.trac.wordpress.org/ticket/64849#ticket

### Summary

The wp_get_image_alttext() function in src/wp-admin/includes/image.php checks for XMP metadata using strpos(), but the current implementation uses a loose comparison:

`php

if ( ! $xmp_start
! $xmp_end ) {

return $alt_text;

}

#2 @suhan2411
4 weeks ago

A patch has been proposed in the GitHub mirror:

https://github.com/WordPress/wordpress-develop/pull/11237

This fixes the strpos() comparison in wp_get_image_alttext() and adds a guard for file_get_contents() returning false.

#3 @joedolson
4 weeks ago

  • Milestone changed from Awaiting Review to 7.0
  • Owner set to joedolson
  • Status changed from new to accepted

#4 @pbiron
4 weeks ago

@suhan2411 Thanx for the report and PR. And welcome to Trac!!!

I've done a quick look at the PR and it looks good to me. However, I won't have a chance to actually test it before 7.0-beta5 is released today.

@joedolson Do you think it will be OK to commit the changes in PR after beta5 but before RC1?

#5 @joedolson
4 weeks ago

@pbiron It's definitely possible to commit before RC1. But we're on the verge of commit freeze for beta 5, so I'm not going to try to sneak it in without taking the time to test, for sure.

#6 @pbiron
4 weeks ago

Thanx Joe. Yes, I wouldn't commit before beta5. I be sure to test things later today or tomorrow.

#7 @alexodiy
4 weeks ago

Tested PR #11237 on PHP 8.5.1 (NTS, Windows x64) against trunk at r61991.

Environment

  • PHP: 8.5.1 (cli) NTS Visual C++ 2022 x64
  • WordPress: 7.0-beta5 (trunk r61991)
  • OS: Windows 11

Reproduction

Created a synthetic binary file where <x:xmpmeta starts at byte position 0, containing valid IPTC AltTextAccessibility metadata with value "Test alt text from XMP".

Before patch:

strpos() returns int(0) for $xmp_start. The check if ( ! $xmp_start ) evaluates ! 0 as true, causing the function to return an empty string. Valid XMP metadata is silently ignored.

After patch:

The check if ( false === $xmp_start ) correctly distinguishes 0 from false. The function extracts and returns the alt text "Test alt text from XMP".

Additional test: file_get_contents failure

When file_get_contents() returns false (e.g., non-existent file path), the added guard if ( false === $img_contents ) prevents passing false to strpos().

Results

Scenario Before Patch After Patch
XMP at position 0 Alt text lost (false negative) Alt text correctly extracted
XMP at position > 0 Works Works
Non-existent file Passes false to strpos() Returns empty string safely

Patch looks correct and minimal. +1 for commit.

#8 @joedolson
4 weeks ago

  • Keywords commit added; needs-testing removed

My tests concur with @alexodiy; these changes are clear improvements. Marking for commit.

#9 @joedolson
4 weeks ago

  • Resolution set to fixed
  • Status changed from accepted to closed

In 62027:

Media: Fix logic when checking IPTC alt text meta data.

Fix two conditional checks for validity of data when importing alt text from IPTC meta data. Strictly compare the results of strpos() as a boolean, rather than treating 0 as false; return string if file_get_contents() returns false.

Props suhan2411, pbiron, alexodiy, joedolson.
Fixes #64849.

Note: See TracTickets for help on using tickets.