Skip to content

[HttpFoundation] Fix file upload multiple with no files #24198

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 30, 2017

Conversation

enumag
Copy link
Contributor

@enumag enumag commented Sep 14, 2017

Q A
Branch? 2.7
Bug fix? yes
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets
License MIT
Doc PR
<form method="post" enctype="multipart/form-data">
<input type="file" multiple name="img[]">
<input type="submit">
</form>

<?php

$loader = require __DIR__ . '/../app/autoload.php';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $request = \Symfony\Component\HttpFoundation\Request::createFromGlobals();
    var_export($request->files->all()['img']);
}

Expected result when I send the form without any files:

array ()

Actual result:

array ( 0 => NULL, )

This causes a problem later when using FileType with multiple option - if no files are sent the form data are [0 => ''] instead of [].

Of course I need to add a test for this.

@xabbuh
Copy link
Member

xabbuh commented Sep 14, 2017

The FileType should handle this quite well since #20418.

@enumag
Copy link
Contributor Author

enumag commented Sep 14, 2017

@xabbuh It does not work because the null is somehow converted to an empty string. I don't know when or why. And regardless I believe this should be fixed in HttpFoundation anyway - some people are using HttpFoundation without Forms.

Should I revert the FileType fix as part of this PR? I don't think it's the right place to fix this issue.

@xabbuh
Copy link
Member

xabbuh commented Sep 14, 2017

Not sure about reverting the change inside the FileType. We may discuss that. However, can you create a test covering the change you are doing here?

@enumag
Copy link
Contributor Author

enumag commented Sep 14, 2017

Of course. I wouldn't want you to merge it without a test anyway.

@enumag enumag force-pushed the patch-27 branch 2 times, most recently from d111996 to 748223c Compare September 14, 2017 09:36
@enumag
Copy link
Contributor Author

enumag commented Sep 14, 2017

@xabbuh Test added. For the Forms component I'd like to remove the FileType::buildForm() method. Other changes from #20418 should stay.

@yceruto Since you're the author of #20418, can I ask for your opinion?

public function testShouldRemoveEmptyUploadedFilesForMultiUpload()
{
$bag = new FileBag(array('file' => array(
'name' => array(''),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really the structure that is used when multiple files are submitted?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xabbuh Yes.

Copy link
Contributor Author

@enumag enumag Sep 14, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be more precise it's the structure used for <input type="file" name="file[]"> (note the []), regardless of how many files are actually sent (including 0) and regardless of the multiple attribute.

You can try yourself with the example script I posted above. Just add var_export($_FILES); somewhere.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the records, that's also explicitly described here: http://php.net/manual/en/features.file-upload.multiple.php

Copy link
Member

@yceruto yceruto Sep 14, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't reproduce the issue, this FileBag with those values returns:

file-bag

according to:

if (UPLOAD_ERR_NO_FILE == $file['error']) {
$file = null;

the rest is handled on PRE_SUBMIT event inside FileType if multiple = true

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See test case also:

public function testSubmitNullWhenMultiple()
{
$form = $this->factory->create(static::TESTED_TYPE, null, array(
'multiple' => true,
));
// submitted data when an input file is uploaded without choosing any file
$form->submit(array(null));
$this->assertSame(array(), $form->getData());
$this->assertSame(array(), $form->getNormData());
$this->assertSame(array(), $form->getViewData());
}

Copy link
Member

@xabbuh xabbuh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me

@xabbuh xabbuh added this to the 2.7 milestone Sep 14, 2017
@xabbuh
Copy link
Member

xabbuh commented Sep 14, 2017

@enumag Can you rebase and change the target branch to 2.7?

@enumag
Copy link
Contributor Author

enumag commented Sep 14, 2017

@xabbuh Sure. Can I ask why? I mean according to Symfony Release Process maintenance for 2.7 already ended. I don't think this qualifies for a security fix.

@xabbuh
Copy link
Member

xabbuh commented Sep 14, 2017

Symfony is an LTS release it receives bugfix until May 2018.

@enumag
Copy link
Contributor Author

enumag commented Sep 14, 2017

Oh right, my mistake. I'll rebase it soon.

@enumag enumag changed the base branch from 2.8 to 2.7 September 14, 2017 12:26
@enumag
Copy link
Contributor Author

enumag commented Sep 14, 2017

@xabbuh All done.

@yceruto
Copy link
Member

yceruto commented Sep 14, 2017

Yep, I think buildForm() and related test case can be removed safely so.

@enumag
Copy link
Contributor Author

enumag commented Sep 18, 2017

@xabbuh Should I remove the buildForm here or in another PR? Perhaps it should only be removed in newer symfony versions to prevent regression when new version of Form component is used with old version of HttpFoundation?

@xabbuh
Copy link
Member

xabbuh commented Sep 20, 2017

We could remove the Form related part, but as you said it may hurt people mixing different versions of the HttpFoundation and Form components. Thus, as it doesn't hurt, I'd vote to keep it as is.

@enumag
Copy link
Contributor Author

enumag commented Sep 20, 2017

Alright. I will send a PR to Forms later when there is no possibility of such conflict.

@fabpot
Copy link
Member

fabpot commented Sep 30, 2017

Thank you @enumag.

@fabpot fabpot merged commit d4f6039 into symfony:2.7 Sep 30, 2017
fabpot added a commit that referenced this pull request Sep 30, 2017
…numag)

This PR was merged into the 2.7 branch.

Discussion
----------

[HttpFoundation] Fix file upload multiple with no files

| Q             | A
| ------------- | ---
| Branch?       | 2.7
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        |

```php
<form method="post" enctype="multipart/form-data">
<input type="file" multiple name="img[]">
<input type="submit">
</form>

<?php

$loader = require __DIR__ . '/../app/autoload.php';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $request = \Symfony\Component\HttpFoundation\Request::createFromGlobals();
    var_export($request->files->all()['img']);
}
```

Expected result when I send the form without any files:

```
array ()
```

Actual result:

```
array ( 0 => NULL, )
```

This causes a problem later when using FileType with multiple option - if no files are sent the form data are `[0 => '']` instead of `[]`.

Of course I need to add a test for this.

Commits
-------

d4f6039 [HttpFoundation] Fix file upload multiple with no files
This was referenced Oct 5, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants