commit 0631777c779599a8ee0634ca306f6dbec1bbcdae Author: Bevan Wishart Date: Sun Jun 14 09:43:08 2020 +1000 870576-58.patch diff --git a/core/modules/file/src/Plugin/Field/FieldType/FileItemMaxFileSizeValidator.php b/core/modules/file/src/Plugin/Field/FieldType/FileItemMaxFileSizeValidator.php index d24c7958c7..35cda5051d 100644 --- a/core/modules/file/src/Plugin/Field/FieldType/FileItemMaxFileSizeValidator.php +++ b/core/modules/file/src/Plugin/Field/FieldType/FileItemMaxFileSizeValidator.php @@ -11,6 +11,15 @@ use Drupal\Core\StringTranslation\TranslatableMarkup; */ class FileItemMaxFileSizeValidator { + /** + * Holds a string representing a byte size to be validated. + * + * @var string $size + * A string size expressed as a number of bytes with optional SI + * or IEC binary unit prefix (e.g. 2, 3K, 5MB, 10G, 6GiB, 8 bytes, 9mbytes). + */ + private static $size; + /** * Form API callback. * @@ -22,21 +31,39 @@ class FileItemMaxFileSizeValidator { */ public static function validateMaxFilesize($element, FormStateInterface $form_state) { - $size = self::stripSpacesFromString($element['#value']); - if (empty($size)) { + // Spaces are irrelevant to us. Bytes::toInt will process with or without + // them. Make our lives easier by just doing away with them. + self::$size = self::stripSpacesFromString($element['#value']); + + // Having removed whitespace, if our string is now empty then the user + // either entered nothing or a string of whitespace. Accept both cases as + // valid. + if (empty(self::$size)) { return; } - if (self::stringIsNotAlphanumeric($size) || - self::stringNotStartWithNumber($size) || - self::hasNumbersFollowingAlphaCharInString($size) || - // Theoretically the above validation should have prevented invalid data - // getting this far. Passing to toInt() for good measure. - !self::toIntCanParseString($size)) { + + // Theoretically self::stringIsValidByteString() should perform strict + // enough validation. Passing the string to Bytes::toInt() for added + // precaution. + if (self::sizeIsValidByteString() || !self::toIntCanParseString()) { $translatable_markup = new TranslatableMarkup('The "@name" option must contain a valid value. You may either leave the text field empty or enter a string like "512" (bytes), "80 KB" (kilobytes) or "50 MB" (megabytes).', ['@name' => $element['#title']]); $form_state->setError($element, $translatable_markup); } } + /** + * Validate the given string looks like a byte size string. + * + * @return bool + */ + private static function sizeIsValidByteString() { + return ( + self::sizeIsNotAlphaNumeric() || + self::sizeNotStartWithNumber() || + self::sizeHasNumbersFollowingAlphaChar() + ); + } + /** * Strips spaces from a string of text. * @@ -53,55 +80,43 @@ class FileItemMaxFileSizeValidator { /** * Determines that a string does not start with a number. * - * @param string $string - * A string representing a size (5mb, 500GB etc) - * * @return bool * TRUE if the string does not start with a numeric char, FALSE otherwise. */ - private static function stringNotStartWithNumber($string) { - return !preg_match('/^\d/', $string); + private static function sizeNotStartWithNumber() { + return !preg_match('/^\d/', self::$size); } /** * Determines if a string has numberic chars following after alpha chars. * - * @param string $string - * A string representing a size (5mb, 500GB etc) - * * @return bool * TRUE if the string has numeric values following after alpha chars. */ - private static function hasNumbersFollowingAlphaCharInString($string) { - return (bool) preg_match('/[a-zA-Z]+(\d+)/', $string); + private static function sizeHasNumbersFollowingAlphaChar() { + return (bool) preg_match('/[a-zA-Z]+(\d+)/', self::$size); } /** * Determines if a string contains non alphanumeric characters. * - * @param string $string - * A string of various characters. - * * @return bool * Returns TRUE if non alphanumeric characters are found. */ - private static function stringIsNotAlphaNumeric($string) { - return (bool) !preg_match('/^[a-zA-Z0-9]+$/', $string); + private static function sizeIsNotAlphaNumeric() { + return (bool) !preg_match('/^[a-zA-Z0-9]+$/', self::$size); } /** * Determines if Bytes:toInt() is able to parse the given string. * - * @param string $string - * A string representing a size (5mb, 500GB etc) - * * @return bool * TRUE if string can be parsed by Bytes::toInt(), FALSE otherwise. */ - private static function toIntCanParseString($string) { + private static function toIntCanParseString() { $valid = TRUE; try { - Bytes::toInt($string); + Bytes::toInt(self::$size); } catch (\Exception $e) { $valid = FALSE;