Problem/Motivation
\Drupal\Component\Utility\Bytes::toInt() passes a string value to round(). In PHP 8 this will trigger an error.
Proposed resolution
Cast the $size value to an integer or a float as appropriate.
Remaining tasks
User interface changes
None
API changes
None
Data model changes
None
Release notes snippet
N/a
| Comment | File | Size | Author |
|---|---|---|---|
| #16 | 3156879-16.patch | 1.05 KB | alexpott |
| #16 | 7-16-interdiff.txt | 453 bytes | alexpott |
| #7 | 3156879-7.patch | 1.03 KB | alexpott |
| #7 | 3156879-7.test-only.patch | 538 bytes | alexpott |
Comments
Comment #2
alexpottComment #3
mondrakeComment #4
krzysztof domański1. The
round()returns float (or false).2. It doesn't matter if we pass an integer
(20)or a float(20.0)toround().Comment #5
krzysztof domańskior much easier
Comment #6
andypostIn a light of php 7.4 https://wiki.php.net/rfc/numeric_literal_separator and https://wiki.php.net/rfc/string_to_number_comparison
This changes needs work
Comment #7
alexpott@andypost i disagree that those changes mean we need to change the fix here. Firstly the numeric literal separator will be stripped by this code:
And there's no need to change that behaviour here. And then
means that we don;t need to do anything for string to number changes.
Here's the change that @Krzysztof Domański suggests and yep it is a bit neater. Doing less work in most cases. I've added a couple of test cases to prove nothing has changed. Therefore the test only patch will not fail. And yep we should fix #3142934: Replace \Drupal\Component\Utility\Bytes::toInt() with \Drupal\Component\Utility\Bytes::toNumber() due to return type sometime soon.
Comment #8
andyposttest-only passes
Comment #9
alexpott@andypost it’s meant to - it proves that the changed code path has not changed functionally.
Comment #10
krzysztof domańskiComment #11
andypostI disagree with change - PHP properly threads floats as strings (after
preg_replace)The code shows that PHP 8 throws notice in case of wrongly formatted numeric-string
but the later does not notice in PHP 7.4
It means this cast just hides error, the same happening in #3156878-3: \Drupal\Component\Datetime\DateTimePlus should pass correct parameter types to checkdate()
Comment #12
alexpott@andypost it's not an error. We are maintaining behaviour that's the best we can do. I'm not sure that people passing 12,2 MB into this method need us to work around PHPs funky number handling.
Comment #13
alexpottAlso more importantly keeps
12,2 bytesbehaving the same as12,2. However running that - https://3v4l.org/XcqDT show we does have a problem - and that #2 was the correct fix.Comment #14
alexpottActually ignore #13. dreditor--
There will NEVER be a comma in $size #11 is incorrect.
#7 is still a good fix. See https://3v4l.org/fQvXm
Comment #15
alexpott@andypost asked why do we need the cast - PHP is doing this for us. Here's why - https://3v4l.org/YpYAQ
The test on DrupalCI that is failing is due to this is
Drupal\Tests\editor\Functional\EditorDialogAccessTest::testEditorImageDialogAccess- see https://dispatcher.drupalci.org/job/drupal_patches/51890/testReport/juni...I still think the fix in #7 is fine.
Compare:
'm'input.Therefore #7 preserves existing behaviour and warnings and looks to be the correct way forward.
Comment #16
alexpottHere's #15 as a test so we have test coverage for the empty string behaviour as the Editor module makes extensive use of it. Search for
'max_size' => ''and you'll see it plenty.Comment #17
krzysztof domańskiI discovered an additional problem looking at https://3v4l.org/OUJaH
bytes_to_int('12,2');returnsfloat(122).I created follow-up. See #3161729: Bytes::toNumber($size) will throw warning is $size failed to parse and #3161730: [META] Refactor \Drupal\Component\Utility\Bytes::toInt().
Comment #20
larowlanCommitted ff72265 and pushed to 9.1.x. Thanks!
c/p to 9.0.x
Leaving open for discussion about backporting
Comment #21
larowlanComment #22
alexpottWe are definitely going to need this to PHP 8 compatibility in Drupal 8 so +1 for backporting.
Comment #23
mondrakeComment #24
alexpottComment #26
larowlanC/p to 8.9.x - thanks
Comment #28
rondog469 commentedThis patch should have probably included a fix for the line above the else:
return round($size * pow(self::KILOBYTE, stripos('bkmgtpezy', $unit[0])));is returning the error: TypeError: Unsupported operand types: string * int in Drupal\Component\Utility\Bytes::toNumber()Comment #29
rondog469 commentedapologies, this issue was for Bytes::toInt which is now deprecated. My issue is with the Bytes::toNumber function albeit it still applies.
Comment #30
mondrake@rondog469 mind opening a new issue with your report? Unlikely anything will happen on an issue that has been closed for 3 years.
Comment #31
rondog469 commented@mondrake Yup I just did and I linked back to this one for reference purposes https://www.drupal.org/project/drupal/issues/3352728