mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2026-10-04 06:37:06 +00:00
Media: Fix TypeError and improve wp_exif_frac2dec() to only return int or float.
For certain images, `wp_exif_frac2dec()` unexpectedly returned a string instead of `int` or `float`. This can occur when an image is missing meta and calls the function with `'0/0'`. For those images, a fatal error was thrown on PHP 8.0+:
{{{
TypeError: round(): Argument #1 ($num) must be of type int|float, string given
}}}
Upon deeper review, inconsistent and unexpected results were returned from different types of input values passed to the function.
Changes are:
* Maintains backwards-compatibility for valid input values.
* Fixes handling of invalid input values by bailing out to return the documented type of `int|float` by returning `0`.
* Improves the fractional conditional check.
* Improves the calculated fraction handling to ensure (a) the numerator and denominator are both numeric and (b) the denominator is not equal to zero.
* Safeguards the behavior via tests for all possible ways code could flow through the function.
* Safeguards the backwards-compatibility of the `wp_read_image_metadata()` by adding some defensive coding around the calls to the `wp_exif_frac2dec()` function.
These changes fix the fatal error and make the function more secure, stable, and predictable while maintaining backwards-compatibility for valid input values.
Follow-up to [6313], [9119], [22319], [28367], [45611], [47287].
Props adamsilverstein, jrf, peterwilsoncc, praem90, stevegs, tobiasbg.
Fixes #54385.
git-svn-id: https://develop.svn.wordpress.org/trunk@52269 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
@@ -700,4 +700,130 @@ class Tests_Image_Functions extends WP_UnitTestCase {
|
||||
unlink( $temp_dir . $size['file'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for wp_exif_frac2dec verified that it properly handles edge cases
|
||||
* and always returns an int or float, or 0 for failures.
|
||||
*
|
||||
* @param mixed $fraction The fraction to convert.
|
||||
* @param int|float $expect The expected result.
|
||||
*
|
||||
* @ticket 54385
|
||||
* @dataProvider data_wp_exif_frac2dec
|
||||
*
|
||||
* @covers ::wp_exif_frac2dec
|
||||
*/
|
||||
public function test_wp_exif_frac2dec( $fraction, $expect ) {
|
||||
$this->assertSame( $expect, wp_exif_frac2dec( $fraction ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testing `wp_exif_frac2dec()`.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function data_wp_exif_frac2dec() {
|
||||
return array(
|
||||
'invalid input: null' => array(
|
||||
'fraction' => null,
|
||||
'expect' => 0,
|
||||
),
|
||||
'invalid input: boolean true' => array(
|
||||
'fraction' => null,
|
||||
'expect' => 0,
|
||||
),
|
||||
'invalid input: empty array value' => array(
|
||||
'fraction' => array(),
|
||||
'expect' => 0,
|
||||
),
|
||||
'input is already integer' => array(
|
||||
'fraction' => 12,
|
||||
'expect' => 12,
|
||||
),
|
||||
'input is already float' => array(
|
||||
'fraction' => 10.123,
|
||||
'expect' => 10.123,
|
||||
),
|
||||
'string input is not a fraction - no slash, not numeric' => array(
|
||||
'fraction' => '123notafraction',
|
||||
'expect' => 0,
|
||||
),
|
||||
'string input is not a fraction - no slash, numeric integer' => array(
|
||||
'fraction' => '48',
|
||||
'expect' => 48.0,
|
||||
),
|
||||
'string input is not a fraction - no slash, numeric integer (integer 0)' => array(
|
||||
'fraction' => '0',
|
||||
'expect' => 0.0,
|
||||
),
|
||||
'string input is not a fraction - no slash, octal numeric integer' => array(
|
||||
'fraction' => '010',
|
||||
'expect' => 10.0,
|
||||
),
|
||||
'string input is not a fraction - no slash, numeric float (float 0)' => array(
|
||||
'fraction' => '0.0',
|
||||
'expect' => 0.0,
|
||||
),
|
||||
'string input is not a fraction - no slash, numeric float (typical fnumber)' => array(
|
||||
'fraction' => '4.8',
|
||||
'expect' => 4.8,
|
||||
),
|
||||
'string input is not a fraction - more than 1 slash with text' => array(
|
||||
'fraction' => 'path/to/file',
|
||||
'expect' => 0,
|
||||
),
|
||||
'string input is not a fraction - more than 1 slash with numbers' => array(
|
||||
'fraction' => '1/2/3',
|
||||
'expect' => 0,
|
||||
),
|
||||
'string input is not a fraction - only a slash' => array(
|
||||
'fraction' => '/',
|
||||
'expect' => 0,
|
||||
),
|
||||
'string input is not a fraction - only slashes' => array(
|
||||
'fraction' => '///',
|
||||
'expect' => 0,
|
||||
),
|
||||
'string input is not a fraction - left/right is not numeric' => array(
|
||||
'fraction' => 'path/to',
|
||||
'expect' => 0,
|
||||
),
|
||||
'string input is not a fraction - left is not numeric' => array(
|
||||
'fraction' => 'path/10',
|
||||
'expect' => 0,
|
||||
),
|
||||
'string input is not a fraction - right is not numeric' => array(
|
||||
'fraction' => '0/abc',
|
||||
'expect' => 0,
|
||||
),
|
||||
'division by zero is prevented 1' => array(
|
||||
'fraction' => '0/0',
|
||||
'expect' => 0,
|
||||
),
|
||||
'division by zero is prevented 2' => array(
|
||||
'fraction' => '100/0.0',
|
||||
'expect' => 0,
|
||||
),
|
||||
'typical focal length' => array(
|
||||
'fraction' => '37 mm',
|
||||
'expect' => 0,
|
||||
),
|
||||
'typical exposure time' => array(
|
||||
'fraction' => '1/350',
|
||||
'expect' => 0.002857142857142857,
|
||||
),
|
||||
'valid fraction 1' => array(
|
||||
'fraction' => '50/100',
|
||||
'expect' => 0.5,
|
||||
),
|
||||
'valid fraction 2' => array(
|
||||
'fraction' => '25/100',
|
||||
'expect' => .25,
|
||||
),
|
||||
'valid fraction 3' => array(
|
||||
'fraction' => '4/2',
|
||||
'expect' => 2,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user