Summary

There is an input/display interaction problem with the File widget edit form's "Allowed file extensions" input field.

Current Operation

  • The "Allowed file extensions" field allows extensions to be separated by either a space or a comma. e.g. "txt doc rtf"
  • When it displays the extensions, they are separated by both a space and a comma. e.g. "txt, doc, rtf"
  • The field has a length restriction of 128.

Problem Statement

It is possible to enter field data which can be saved once, but not can be saved if the field is edited at a later time.

Example

  • If you enter a list of 30 extensions, each 3 characters long separated by a space, the line length is 119 characters (30x4-1) and will be saved.
  • When the field is displayed on the next edit the field value now has an extra character per extension. The space has been transformed into a space plus comma. The length is now 148 characters (30x5-2) and can not be saved.
  • Error message: Allowed file extensions cannot be longer than 128 characters but is currently 148 characters long

Work Around

Edit the field content to remove commas or spaces.

Possible Solutions

  • Display the extensions separated by only a space
  • Make the length checking sophisticated enough to take the input and display differences into account

Issue fork drupal-1708476

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:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Danny Englander’s picture

I think this is probably related, I just ran into this issue myself. Once it's done for Drupal 8, it will hopefully be back-ported for Drupal 7.

marcingy’s picture

Status: Active » Closed (duplicate)
dale42’s picture

Status: Closed (duplicate) » Active

This is not a duplicate of #997900. That issue refers to the inability of using a wild card or some other method to allow any file to be uploaded.

This issue refers to a case where it is possible to enter a string of extensions and then not be able to go back and edit/save the form because the system has displayed the string differently, making it longer than the allowable field length. i.e. It's possible to save a string of file extensions and not be able to subsequently edit/change it.

The extremely long field length solution in #997900 would mitigate this issue, but if the separation character is changed from " " to ", " the issue could still occur.

Danny Englander’s picture

@dale42 -- Thanks for the clarification, that makes sense now, indeed they do sound like different issues.

acbramley’s picture

Version: 7.14 » 7.19
FileSize
591 bytes

Encountered the maxlength problem when trying to...well...add more than 128 characters. I don't see why this limitation would exist. Here's a patch to increase it to 255.

boyan.borisov’s picture

Status: Active » Needs review
vacho’s picture

This patch works (#5)

WebSinPat’s picture

patch in #5 works for me.

seanr’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community

This same bug afflicts the file_entity module. I can confirm that this same fix works in both instances with no adverse effects. Marking RTBC.

ar-jan’s picture

Version: 7.19 » 7.x-dev

Changing version, since this isn't fixed yet.

David_Rothstein’s picture

Version: 7.x-dev » 8.x-dev
Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs backport to D7

As far as I can see, this affects Drupal 8 too, so would need to be fixed there first.

Boobaa’s picture

Status: Needs work » Needs review
FileSize
793 bytes

Here's a forward port of #5 to D8.

Boobaa’s picture

Here's another patch that:

  • is a forward port of #5 to D8 (raises the limit to 255);
  • removes the commas the form builder adds to the stored settings;
  • removes any and all signs of commas related to this setting: from the setting's default value, the description, the validation and the error message.

I don't know if a test is necessary; probably not, as there were no tests for the 128-character limit either. That limit of 128 characters is implicitly added by Form API: a textfield's default #maxlength is 128. OTOH, the 255-character limit is just a bit higher: it could be even 1024 or 65535 or 2,147,483,648 or just about any size a config entity setting can hold.

jhedstrom’s picture

Status: Needs review » Needs work
Issue tags: +Needs re-roll, +Needs tests

That limit of 128 characters is implicitly added by Form API: a textfield's default #maxlength is 128. OTOH, the 255-character limit is just a bit higher: it could be even 1024 or 65535 or 2,147,483,648 or just about any size a config entity setting can hold.

Seems if we're going to bother changing it, it should go up to at least 1024.

A test here, particularly one for the commas the form builder adds, that shows the current failure and illustrates the fix would be valuable I think.

Also, the current patch no longer applies.

jhedstrom’s picture

Issue tags: -Needs re-roll +Needs reroll
gbisht’s picture

Status: Needs work » Needs review
Issue tags: +SprintWeekend2015
FileSize
2.17 KB

Patch Rerolled!

msound’s picture

Assigned: Unassigned » msound

Reviewing...

msound’s picture

Status: Needs review » Needs work

Patch #16 does not work. `form_error` is an undefined function in D8.

Also, when I add a new extenstion and save and come back to the form, my extension is missing.

I'm working on a patch.

manningpete’s picture

Issue tags: -Needs reroll

Patch applies, removing reroll.

msound’s picture

Assigned: msound » Unassigned
Status: Needs work » Needs review
Issue tags: -Needs tests
FileSize
4.04 KB

This patch builds on top of work done already. The problem with patches #13 and #16 is that they use D7's `form_error` function, which is not defined in D8. It appears that simple test is passing for those patches because the testing does not flow through that code. So, I've written additional simple tests.

msound’s picture

Changed the assert in #20 to a better one.

jhedstrom’s picture

Thanks for adding a test! Can you upload a separate patch file that only includes the test so it can illustrate the current failure?

msound’s picture

This patch is only to demonstrate the current failure in the "allowed extensions" field.

@jhedstrom Do you want me to re-roll #21 with this modification (hitting "save" twice) for regression purposes?

Status: Needs review » Needs work

The last submitted patch, 23: drupal-allowed-file-extensions-1708476-23.patch, failed testing.

jhedstrom’s picture

Status: Needs work » Needs review

@msound sure, but also perhaps update the code comment as to why the double save is needed?

mgifford’s picture

Status: Needs review » Needs work
BarisW’s picture

It might be me, but why do we make it so hard for people to enter file extensions? Does it really matter how people enter the extensions?
It's quite easy to filter out comma's, spaces and semicolons.

Can't we simply remove the description and explode on several characters, something like:

<?php
$extensions = preg_split( "/ (,|;| |) /", str_replace('.', '', $input));
?>

Then we sure need to fix the issue with length of the textfield. Let's increase it to 255 and set a #max_length to 200?

jhedstrom’s picture

Allowing different separators makes sense to me.

Then we sure need to fix the issue with length of the textfield. Let's increase it to 255 and set a #max_length to 200?

The length is already at 256--this patch bumps to 1024.

msound’s picture

Assigned: Unassigned » msound
msound’s picture

This is a re-roll of #23 with clear comments. This patch should FAIL thereby proving the bug exists in core.

msound’s picture

I am working on re-rolling patch #21 to include the above simpletest in patch #30.

msound’s picture

Assigned: msound » Unassigned
Status: Needs work » Needs review
FileSize
4.99 KB

Patch attached. This patch ensures that only space is used as the delimiter. This way user can make full use of the allowed 1024 characters.

This patch also cleans user input, so even if they entered periods or commas, the input will be cleaned up and accepted.

adamexmachina’s picture

Assigned: Unassigned » adamexmachina

I'm working on this at DrupalCon LA.

adamexmachina’s picture

Assigned: adamexmachina » Unassigned

I have tested patch #32 and it works for me.

+1

bnjmnm’s picture

I'm at DrupalCon and reviewing this patch

Boobaa’s picture

I'm not at DrupalCon LA (oh wait, it's over), but had a look at the patch in #32 and it looks good. I'm not marking as RTBC because I haven't tested it.

mgifford’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community
FileSize
27.6 KB

I looked over the code. I also compared it to the site without the patch. This is a simper way forward:

I also confirmed I could us a much longer string - "txt doc wpd rdf drd3 fed3 def2 pwd pwd3 d4 de df dag ded ed dad rad nad tad jss ddd rd 3n dl 88 non none rlan ln ee re nle dea e0 dn0 no dr3 nnn ll rr nn fish h dee dg dse drd lfl wed mom ewl eee fff ggg sss wfw qqw qeqw wwq ww bb lll ere3 vdd3 se si9 le9 bad cdad sad lal lad dal ni l nil u8 ede rkrk rk kr kkr rkk" with the patch than without.

I did notice that there was no error if you went above the character length without the patch (and assume there is none with the patch either). That isn't a blockage for this issue, just something I'm noticing.

Added the string via the content types admin/structure/types/manage/article/fields/node.article.field_file

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/modules/file/src/Plugin/Field/FieldType/FileItem.php
    @@ -162,16 +162,14 @@ public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
    -    // Make the extension list a little more human-friendly by comma-separation.
    
    It is possible to enter field data which can be saved once, but not can be saved if the field is edited at a later time.

    This is a nice bug find. And yep the fix of being less human-friendly in one way but way more human friendly in other makes sense to me :)

  2. +++ b/core/modules/file/src/Plugin/Field/FieldType/FileItem.php
    @@ -162,16 +162,14 @@ public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
    -      '#description' => t('Separate extensions with a space or comma and do not include the leading dot.'),
    ...
    +      '#description' => t('Separate extensions with a space and do not include the leading dot.'),
    
    @@ -227,11 +225,11 @@ public static function validateDirectory($element, FormStateInterface $form_stat
    +      $extensions = preg_replace('/([\., ]+)/', ' ', trim(strtolower($element['#value'])));
    ...
    -        $form_state->setError($element, t('The list of allowed extensions is not valid, be sure to exclude leading dots and to separate extensions with a comma or space.'));
    +        $form_state->setError($element, t('The list of allowed extensions is not valid, be sure to exclude leading dots and to separate extensions with a space.'));
    

    why are we replacing commas here now they are not used? If we do want to do this it should be tested. I think it might make since to do this but... then the description should probably not be changed.

  3. +++ b/core/modules/file/src/Plugin/Field/FieldType/FileItem.php
    @@ -162,16 +162,14 @@ public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
    -      '#maxlength' => 256,
    +      '#maxlength' => 1024,
    

    Why have a max length? Afaik the config storage does not have a limit.

  4. +++ b/core/modules/file/src/Tests/FileFieldValidateTest.php
    @@ -158,4 +158,50 @@ function testFileExtension() {
    +    // Test extensions with periods and commas. The field should be forgiving
    +    // of the user input and clean the input and accept it.
    +    $edit = array();
    +    $extensions = array();
    +    while (count($extensions) < 5) {
    +      $rnd_ext = $this->randomMachineName(3);
    +      if (!in_array($rnd_ext, $extensions)) {
    +        $extensions[] = '.' . $rnd_ext;
    +      }
    +    }
    +    $edit['settings[file_extensions]'] = implode(', ', $extensions);
    +    $this->drupalPostForm('admin/structure/types/manage/article/fields/node.article.' . $field_name, $edit, t('Save settings'));
    +    $this->assertText("Saved $field_name configuration", 'File field saved successfully even when user input contained periods and commas.');
    

    ONly has periods now - the field no longer ignores commas

deepakaryan1988’s picture

Issue tags: -SprintWeekend2015

Removing sprint weekend tag!!
As suggested by @YesCT

deepakaryan1988’s picture

Issue tags: +SprintWeekend2015

Sorry, these issues were actually worked on during the 2015 Global Sprint
Weekend https://groups.drupal.org/node/447258

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.

aerozeppelin’s picture

Updated patch as per comments in #38.

Why have a max length? Afaik the config storage does not have a limit.

Removing the max length resulted in failing tests. So, had to keep it.

The last submitted patch, 43: test-only-fail-1708476-43.patch, failed testing.

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.

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

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

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

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

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Lendude’s picture

Needed a reroll, so started with that. But the logic of allowed extensions has become a bit more complex since this was last rolled due to things like #3166044: Allow file extensions containing underscores

I'm not sure if we should add the bit where we are lenient about the starting dot here. If we want that, we should probably add it in a separate issue since it is something of a feature vs the bug we are trying to fix here.

So for now I've taken that out and just removed the artificial padding with commas on display and added the test coverage. Sorry no interdiff because of the reroll.

The last submitted patch, 54: 1708476-54-TEST_ONLY.patch, failed testing. View results

Lendude’s picture

Version: 9.4.x-dev » 10.0.x-dev
FileSize
740 bytes
3.99 KB

Fix the other test.

Needs a different patch for 9.4/9.5 and not going to bother with that until this lands, so moving to D10

acbramley’s picture

Status: Needs review » Reviewed & tested by the community

Manually tested successfully, including adding commas between extensions when configuring via the form.

Agree with #55 that we should handle the leading dot in a follow-up.

acbramley’s picture

Issue tags: +Bug Smash Initiative
quietone’s picture

Status: Reviewed & tested by the community » Needs work

Sorry, I think my comment in #bugsmash was mis-understood.

+++ b/core/modules/file/tests/src/Functional/FileFieldValidateTest.php
@@ -162,6 +162,31 @@ public function testFileExtension() {
+      $rnd_ext = $this->randomMachineName(3);

The first time I ran the test a string of 'php' was created which will cause the test to fail. I think the final array needs to be stripped of any extensions that will cause a failure.

Version: 10.0.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.