In D8:

File field's Maximum upload size is validated by:

<?php
  public static function validateMaxFilesize($element, FormStateInterface $form_state) {
    if (!empty($element['#value']) && !is_numeric(Bytes::toInt($element['#value']))) {
      $form_state->setError($element, t('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).', array('!name' => t($element['title']))));
    }
  }
?>

This function has 2 bugs:
- It will always validate because Bytes::toInt() always returns a number.
- It is not $element['title'] but $element['#title']

In D7:

File field's Maximum upload size is validated by:

<?php
function _file_generic_settings_max_filesize($element, &$form_state) {
  if (!empty($element['#value']) && !is_numeric(parse_size($element['#value']))) {
    form_error($element, t('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).', array('!name' => t($element['title']))));
  }
}
?>

This function has 2 bugs:
- It will always validate because parse_size() always returns a number.
- It is not $element['title'] but $element['#title']

Issue fork drupal-2359675

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

anrikun’s picture

Status: Active » Needs review
StatusFileSize
new1.03 KB

Here is a patch.

anrikun’s picture

Version: 7.x-dev » 8.0.x-dev
StatusFileSize
new1.18 KB

The same bug is also present in 8.0.x

anrikun’s picture

Issue summary: View changes
jhedstrom’s picture

StatusFileSize
new1.58 KB
new1.58 KB
new2.76 KB

This adds a test.

The last submitted patch, 4: max-filesize-validate-2359675-04-TEST-ONLY.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 4: max-filesize-validate-2359675-04.patch, failed testing.

jhedstrom’s picture

Weird. I didn't notice the t() function when testing locally these worked for some reason.

jhedstrom’s picture

Status: Needs work » Needs review
StatusFileSize
new942 bytes
new1.78 KB
new2.95 KB

I'm guessing this won't be allowed, but Views does it, and it illustrates the fix. I could have sworn there was an issue out there somewhere to add \Drupal::t() for use in static methods like this, but I couldn't find it.

The last submitted patch, 8: max-filesize-validate-2359675-08-TEST-ONLY.patch, failed testing.

mgifford’s picture

Status: Needs review » Needs work

Needs re-roll.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

grimreaper’s picture

Version: 8.9.x-dev » 9.2.x-dev
Assigned: Unassigned » grimreaper
Issue tags: +Europe2020
grimreaper’s picture

grimreaper’s picture

Ok, my bad I was not testing the right thing.

I was testing the upload in a field. Not the settings form of the field...

Confirming that there is still the bug.

grimreaper’s picture

Status: Needs work » Needs review

MR created, I have removed an unused statement in the test file. And kept the "@name" instead of changing into "!name".

I don't know if credits will be applied properly as selectin "author" and "by" does not change the commit command and I didn't commit with my drupal.org user account email address.

grimreaper’s picture

grimreaper’s picture

Assigned: grimreaper » Unassigned
lendude’s picture

Not sure what we want to do with the commented out test cases

grimreaper’s picture

Yes, me too, that's why I need some feedbacks :). Replied in the MR.

grimreaper’s picture

Assigned: Unassigned » grimreaper
Status: Needs review » Needs work

For the record, when uncommeting thelines, this is the warning message:

Warning: A non-numeric value encountered in Drupal\Component\Utility\Bytes::toNumber() (line 55 of core/lib/Drupal/Component/Utility/Bytes.php).
Drupal\Component\Utility\Bytes::toNumber('') (Line: 249)
Drupal\file\Plugin\Field\FieldType\FileItem::validateMaxFilesize(Array, Object, Array)
call_user_func_array(Array, Array) (Line: 280)
Drupal\Core\Form\FormValidator->doValidateForm(Array, Object) (Line: 236)
Drupal\Core\Form\FormValidator->doValidateForm(Array, Object) (Line: 236)
Drupal\Core\Form\FormValidator->doValidateForm(Array, Object, 'field_config_edit_form') (Line: 118)
Drupal\Core\Form\FormValidator->validateForm('field_config_edit_form', Array, Object) (Line: 589)
Drupal\Core\Form\FormBuilder->processForm('field_config_edit_form', Array, Object) (Line: 321)
Drupal\Core\Form\FormBuilder->buildForm(Object, Object) (Line: 73)
Drupal\Core\Controller\FormController->getContentResult(Object, Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 573)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 158)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 80)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 706)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
require('/project/app/index.php') (Line: 4)
grimreaper’s picture

Assigned: grimreaper » Unassigned
Status: Needs work » Needs review
lendude’s picture

Status: Needs review » Needs work

Added some feedback to the MR

grimreaper’s picture

Status: Needs work » Needs review

Thanks @Lendude for the review.

Test cases added.

liber_t’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +GlobalContributionWeekend2021

Good for me

rachel_norfolk’s picture

Issue tags: -GlobalContributionWeekend2021 +ContributionWeekend2021

Just doing a little tag tidying. Nice work everyone!!

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

Do we need to check that current values are valid? I think it is okay... atm invalid values like 'five' will be determined to be 0 which means that it will be ignored in file_validate_size(). The user will then be prompted to fix this if they save the field again.

Maybe we should consider adding a Bytes::validate() method to validate a string representation and use that here? For example '1five' is still considered valid!

>>> \Drupal\Component\Utility\Bytes::toNumber('1five');
=> 1.1529215046068E+18

And would result in a v. large maximum filesize.

If we added a generic string validation method on the utility class then anywhere else that accepts a byte string could use it.

grimreaper’s picture

Assigned: Unassigned » grimreaper
grimreaper’s picture

Assigned: grimreaper » Unassigned
Status: Needs work » Needs review

Hello,

validate method added to the Bytes utility class as asked in comment 34.

I kept the test for the validateMaxFilesize method.

I made an allowed suffixes constant to avoid side effects and not catched cases with regex. If there is a better approach, please suggest.

Thanks for the review.

grimreaper’s picture

Assigned: Unassigned » grimreaper

Checking.

grimreaper’s picture

Assigned: grimreaper » Unassigned

Tests are back to green.

Thanks for the review.

grimreaper’s picture

Assigned: Unassigned » grimreaper
grimreaper’s picture

Assigned: grimreaper » Unassigned

Tests added.

Ready fo review again.

grimreaper’s picture

Issue tags: +Bug Smash Initiative
dww’s picture

Status: Needs review » Needs work

NW for the review points in the MR.

Also, is it worth a functional test showing end-to-end that a bogus value for this limit can be saved and then ignored by uploading a real file? I'd feel a bit safer RTBC'ing this if we weren't only testing the lowest level parts of this, but actually seeing the real bug we're fixing as a test-only fail that becomes green with the rest of the fix applied...

grimreaper’s picture

Assigned: Unassigned » grimreaper
grimreaper’s picture

Assigned: grimreaper » Unassigned
Status: Needs work » Needs review

Hello,

Thanks @dww for the review!

Review points taken into account except one https://www.drupal.org/project/drupal/issues/2359675#mr127-note20090 for which I am waiting more people opinion.

About comment #2359675-42: File field's Maximum upload size always passes validation, I am not sure to understand what you mean because the bug is on the field config form, not on an entity form. So I don't think this is needed to go to the point to test a file upload.

Also with this patch it is now not possible to configure a bad value for the maximum upload size, so how did you imagine such test?

nicoloye’s picture

Status: Needs review » Reviewed & tested by the community

The proposed MR seems ok to me !

larowlan’s picture

Status: Reviewed & tested by the community » Needs review
paulocs’s picture

Status: Needs review » Needs work

I'll work on it.
Set back to nw because of #46.

paulocs’s picture

I didn't create a trait as @larowlan pointed bacause if we trim the input, the list must be edited so they get different between each other.
I didn't addressed what @dww pointed because as the lists are different I'm not sure what the best approach is.

Maybe we can reduce the list in FileItemTest just to the tests cases that are different from list in Bytes.php?

paulocs’s picture

Status: Needs work » Needs review

I addressed what @larowlan and @dww pointed.
Please review!

Cheers, Paulo.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

grimreaper’s picture

Version: 9.3.x-dev » 10.0.x-dev
Assigned: Unassigned » grimreaper
Status: Needs review » Needs work

I have pointed out to Slack that the issue version is 10.0.x-dev where comment 50 assigned it to version 9.3.x-dev (https://drupal.slack.com/archives/C51GNJG91/p1619869940156900)

Thanks @paulocs for the update.

I will complete a little bit the functional test.

grimreaper’s picture

Assigned: grimreaper » Unassigned
Status: Needs work » Needs review

Functional test completed.

Needs review!

grimreaper’s picture

Version: 10.0.x-dev » 9.3.x-dev
paulocs’s picture

Status: Needs review » Reviewed & tested by the community

For me it looks good!

grimreaper’s picture

Hello,

Just poking the issue, I don't think there is anything left to be done :)

larowlan’s picture

Status: Reviewed & tested by the community » Needs review

Hi @Grimreaper, @paulocs this looks good to me, I have just one comment about an extra test case.

Please feel to ping me for another look when this is ready.

Lee

  • catch committed ff8ead8 on 9.3.x
    Issue #2359675 by Grimreaper, jhedstrom, paulocs, anrikun, Lendude,...

larowlan credited catch.

larowlan’s picture

Saving issue credits

  • catch committed ca6acb2 on 9.2.x
    Issue #2359675 by Grimreaper, jhedstrom, paulocs, anrikun, Lendude,...
catch’s picture

Version: 9.3.x-dev » 9.2.x-dev
Status: Needs review » Fixed

(whoops, cross-post with larowlan).

Looks good to me as well.

I had to think for a bit about toNumber() being able to translate units without needing the list of allowed values, vs validation needing an explicit list, but I think this is fine . toNumber() is doing some trickery with string ordering and powers, which will allow some 'invalid' values (i.e. it would accept killerbytes because it's only looking for 'k'), but there's no reason to make that more restrictive, or to make the validation less restrictive, because they're doing different things.

Committed/pushed to 9.3.x and cherry-picked to 9.2.x, thanks!

catch’s picture

Status: Fixed » Needs review

Re-opening for discussion - but we should either roll back or open a follow-up rather than commit two patches.

grimreaper’s picture

Hello,

Thanks @larowlan for the review.

Ok to write a new test in a follow-up issue. Can someone just give some advice on what to write exactly please?

@catch thanks for the commits!

paulocs’s picture

Hello Grimreaper,
I think we should add '300 0' to providerTestValidate.

I'll open a follow-up issue to add the test.

paulocs’s picture

catch’s picture

Status: Needs review » Fixed

Thanks for opening the follow-up, marking this fixed again.

grimreaper’s picture

@paulocs Thanks for the follow-up issue.

Ok, clear now, I didn't realize it was the "$string = '300 0';" the use case of the online example, sorry.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

catch’s picture

thursday_bw’s picture

@catch

Is it just an oversite that credit was not assigned for all the effort put into to https://www.drupal.org/project/drupal/issues/870576 ?

It is heartedly discouraging to put significant effort into an issue simply to have it all thrown away by a duplicate issue.

larowlan credited heddn.

larowlan credited jungle.

larowlan credited pavnish.

larowlan credited quietone.

larowlan’s picture

@bevan.wishart@gmail.com yeh that was definitely an oversight mate - copying over the credit from the other issue.

Feel free to ask if this happens again, we're all human