\Drupal\Component\Utility\Bytes::toNumber() - $size must be a number in PHP 8+

Created on 6 April 2023, over 1 year ago
Updated 7 July 2023, over 1 year ago

Problem/Motivation

\Drupal\Component\Utility\Bytes::toNumber() - ensure $size is a number. Near duplicate of the toInt() issue, but toInt is now deprecated.

https://www.drupal.org/project/drupal/issues/3156879 🐛 \Drupal\Component\Utility\Bytes::toInt() - ensure $size is a number type Fixed

While I selected drupal version 10, this would apply to 8, 9, 10+

Steps to reproduce

Using PHP 8+ a TypeError is thrown: TypeError: Unsupported operand types: string * int in Drupal\Component\Utility\Bytes::toNumber() (line 99 of /core/lib/Drupal/Component/Utility/Bytes.php)

For me this happens when trying to edit the user profile picture. This is migrated content from D7 so maybe that is why this error is being thrown. Regardless, $size should be a number and not a string.

Proposed resolution

Cast $size as a float.
before:
return round($size * pow(self::KILOBYTE, stripos('bkmgtpezy', $unit[0])));
after:
return round((float) $size * pow(self::KILOBYTE, stripos('bkmgtpezy', $unit[0])));

🐛 Bug report
Status

Needs work

Version

11.0 🔥

Component
Base 

Last updated about 1 hour ago

Created by

🇺🇸United States rondog469

Live updates comments and jobs are added and updated live.
  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • Issue created by @rondog469
  • 🇺🇸United States rondog469

    patch for described issue

  • 🇺🇸United States rondog469

    looking more into this issue, with this patch I can now edit my user picture field and this problem has to stem from migrating. The file size value set on this field is just "KB". The is incorrect. Even though the display value on the field's file size limit is just "KB", when I output `$size` its "1024".

    Again, this issue must stem from migrating, but I also think $size should still be casted as a number anyway.

  • 🇫🇷France andypost

    It could use to add type checking and throw deprecation if the $size is not int|float and in D11 we can add type hint to function

  • Status changed to Needs review over 1 year ago
  • Status changed to Needs work over 1 year ago
  • 🇺🇸United States smustgrave

    Would like to know the exact scenario that is triggering this. If it's a bad contrib module.

    But like the idea @andypost suggested of adding a type check and throw deprecation.

    Then a test case to reflect that.

  • 🇳🇿New Zealand danielveza Brisbane, AU

    I don't think we can typehint the function because it's valid to pass a string - E.g. '1MB'

    What about throwing a LogicException if the passed string can't be converted to a number? Attached a patch as a POC. This approach seems to make sense because if you pass an invalid string currently you get an exception, so this at least makes it more clear what the problem is.

  • 🇺🇸United States rondog469

    @smutgrave, I dont know the exact scenario, but this happened when viewing the user profile picture field after migrating a drupal 7 site to drupal 9. On the d7 site the field in question did not have a size set. After migrating the size value of the field was set to just "KB", no number prepended to it.

  • Status changed to Needs review over 1 year ago
  • last update over 1 year ago
    29,802 pass
  • 🇮🇳India Ajeet Tiwari

    Please review.

  • Status changed to Needs work over 1 year ago
  • 🇺🇸United States smustgrave

    Please read the tags and apply interdiffs

    Also you patch seems to be removing things from #7 without explanation.

    Tests are still needed

Production build 0.71.5 2024