Opened 9 months ago
Last modified 4 days ago
#64480 new defect (bug)
WordPress PHP Deprecated: Implicit conversion from float 44.168
| Reported by: | sotnas | Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | Awaiting Review |
| Component: | Media | Version: | 6.9 |
| Severity: | normal | Keywords: | has-patch has-unit-tests reporter-feedback |
| Cc: | Focuses: | php-compatibility |
Description
Hi,
WP V6.9
PHP 8.1
And give me
Wordpress PHP Deprecated: Implicit conversion from float 44.168 to int loses precision in /home/cpanel/public_html/wp-includes/media.php on line 1500
In wp-content/debug.log
Why?
Change History (9)
#2
follow-up:
↓ 4
@
9 months ago
I assume the error comes from this block of code:
// The 'src' image has to be the first in the 'srcset', because of a bug in iOS8. See #35030.
if ( $is_src ) {
$sources = array( $image['width'] => $source ) + $sources;
} else {
$sources[ $image['width'] ] = $source;
}
Since $image['width'] is used as an array key, an implicit float-to-int conversion can occur under PHP 8.1.
Casting the value explicitly beforehand should resolve the warning:
$width = (int) $image['width'];
and then using $width as the array key.
That said, the open question is why $image['width'] can be a float in the first place, given that image dimensions are generally expected to be integers.
#3
@
9 months ago
Could the site have an SVG attachment with 44.168 as the width or a value in the viewBox attribute?
Safe SVG uses floatval() to set dimensions for SVG, but it gave me integers when I tried uploading the following graphics:
1. viewBox-20.2x20-safe.svg dimensions: 20 × 20, from viewBox <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20.2 20"><circle cx="7" cy="7" r="5"/><circle cx="9" cy="9" r="5"/></svg> 2. 20.2w20h-safe.svg dimensions: 202 × 200, from viewBox <svg xmlns="http://www.w3.org/2000/svg" width="20.2" height="20" viewBox="0 0 202 200"><circle cx="100" cy="100" r="100"/></svg> 3. 20.2w20h-safe2.svg dimensions: 20 × 20, from width and height attributes because I used add_filter( 'safe_svg_use_width_height_attributes', '__return_true' ); <svg xmlns="http://www.w3.org/2000/svg" width="20.2" height="20" viewBox="0 0 202 200"><circle cx="100" cy="100" r="100"/></svg>
#4
in reply to: ↑ 2
@
9 months ago
Casting the value explicitly beforehand should resolve the warning
The wp_image_matches_ratio() function in line 1488 expects all four parameters to be integers.
If $image['width'] is not an integer, I would suggest using either
continueto try another image size in the loop orreturn false(wp_calculate_image_srcset()returns "False on error or when only one source exists").
In this function, I think I prefer returning false when encountering unexpected input instead of adding continue, casting, or _doing_it_wrong(). Then the image simply would not get a srcset attribute.
Float values might create problems elsewhere too, but then the other place(s) could be better to give an error message or warning.
This ticket was mentioned in PR #13703 on WordPress/wordpress-develop by @therssoftware.
12 days ago
#5
- Keywords has-patch has-unit-tests added
Trac ticket: https://core.trac.wordpress.org/ticket/64480
Description
In PHP 8.1+, using float values as array keys triggers PHP Deprecated: Implicit conversion from float to int loses precision and in future PHP versions will cause a TypeError. Furthermore, the HTML specification requires srcset width descriptors to be positive integers.
This change rounds and casts the image width to an integer before adding it to the sources array and descriptor value, and verifies the width is at least 1. Includes unit test coverage for float dimensions.
Props therssoftware.
#6
@
12 days ago
- Focuses php-compatibility added
- Keywords needs-testing added; reporter-feedback removed
I have created PR 13703 addressing this issue.
- Rounds and casts
$image['width']to an integer before indexing the$sourcesarray and assigning the descriptor value. - Verifies the calculated width is at least 1.
- Conforms to the HTML srcset specification for width descriptors.
- Includes a unit test verifying float dimensions without PHP deprecation notices.
#7
@
6 days ago
- Keywords 2nd-opinion added
The attached PR rounds the value, which differs from how PHP behaves when passing a float for use as a key. @sabernhardt suggested returning false. Can we get an opinion from a maintainer on the desired approach?
#8
follow-up:
↓ 9
@
6 days ago
- Keywords 2nd-opinion removed
Thanks so much for the patch @therssoftware!
While I'm also curious how a float value came about in the first place, I personally like the idea of either casting directly to (int) to solve this issue.
Unless there is a common situation I'm missing where there are image sets where some are intended to have float widths / heights, having the least user friction (as @therssoftware referred to in PR) is preferred to me.
Having a partial srcset rather than none feels to me like a more expected user experience if one of the sizes isn't formatted properly.
@sabernhardt On the approach you recommended: Where do you think the feedback would be best returned?
#9
in reply to: ↑ 8
@
4 days ago
- Keywords reporter-feedback added; needs-testing removed
how a float value came about in the first place
I think we need a sample image and steps to reproduce this before moving forward. If the float value comes from an SVG, the srcset could match the src file. If it happens with any other formats, then the number may require casting to an integer.
Where do you think the feedback would be best returned?
I would expect a problem when trying to assign a float value to width and/or height attributes, if that can occur. Feedback could be more important in that situation.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
@sotnas Welcome to Trac. Can you provide more information to help troubleshoot the issue? What steps are you taking to trigger this notice? Would you mind installing the Test Reports plugin and sharing the Bug Report for Trac? https://wordpress.org/plugins/test-reports/