Skip to content

[HttpFoundation] Fix unprepared BinaryFileResponse sends empty file #28278

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
Aug 27, 2018
Merged

[HttpFoundation] Fix unprepared BinaryFileResponse sends empty file #28278

merged 1 commit into from
Aug 27, 2018

Conversation

j4nr6n
Copy link
Contributor

@j4nr6n j4nr6n commented Aug 26, 2018

Q A
Branch? 2.8
Bug fix? yes
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes, with the exception of preexisting, unrelated failures
Fixed tickets #28237
License MIT
Doc PR

When you call BinaryFileResponse#sendContent() without first calling prepare() the response is sent but the contents are empty. prepare() properly initializes the $maxlen and $offset properties. However, sendContent() doesn't do any sanity checking, and so, uses the uninitialized properties. This causes stream_copy_to_stream() to copy empty contents and the file that is sent, to contain nothing.

This change initializes the properties at definition instead of in prepare().

Additionally:

  • Bug fixes must be submitted against the lowest branch where they apply

I'm not sure how early this bug exists, or how far back to go. I'll check to see if 2.7 and 2.8 are affected and report back.

@j4nr6n
Copy link
Contributor Author

j4nr6n commented Aug 26, 2018

Test app, for reference

@nicolas-grekas nicolas-grekas added this to the 2.8 milestone Aug 27, 2018
@@ -201,9 +201,6 @@ public function prepare(Request $request)

$this->ensureIEOverSSLCompatibility($request);

$this->offset = 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

i think we should keep this in case of multiple calls to prepare().

Technically initializing the properties with default values can break some edgy code, relying on the the lazy null. Perhaps better to default on the calling side: $this->offset ?? 0?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The null-coalesce operator isn't available until PHP 7.0. I thought 2.8 needed to support PHP 5.3.9+. I could use ?: but then if $offset is set to 0 by prepare(), the ternary will evaluate to false. That's probably not that big of an issue in this case since it would be set to 0 anyway.

I did restore the default values in prepare() though.

{
$response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200);

$file = fopen(__DIR__.'/File/Fixtures/test.gif', 'r');
Copy link
Member

Choose a reason for hiding this comment

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

I'd suggest to use file_get_contents here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. Updated.

Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

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

LGTM, with one minor comment.
Should target 2.8 (2.7 is not maintained anymore, except for security bugs - rebase can be done while merging).

@nicolas-grekas nicolas-grekas changed the title [ HttpFoundation ] Unprepared BinaryFileResponse sends empty file. [ HttpFoundation ] Unprepared BinaryFileResponse sends empty file Aug 27, 2018
@nicolas-grekas nicolas-grekas changed the title [ HttpFoundation ] Unprepared BinaryFileResponse sends empty file [HttpFoundation] Fix unprepared BinaryFileResponse sends empty file Aug 27, 2018
@j4nr6n j4nr6n changed the base branch from 2.7 to 2.8 August 27, 2018 13:02
@j4nr6n
Copy link
Contributor Author

j4nr6n commented Aug 27, 2018

Thanks @nicolas-grekas, I've updated the target branch.

Copy link
Member

@fabpot fabpot left a comment

Choose a reason for hiding this comment

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

LGTM to you still need to call prepare() anyway.

@fabpot
Copy link
Member

fabpot commented Aug 27, 2018

Thank you @WackyMole.

@fabpot fabpot merged commit dba8687 into symfony:2.8 Aug 27, 2018
fabpot added a commit that referenced this pull request Aug 27, 2018
…mpty file (wackymole)

This PR was merged into the 2.8 branch.

Discussion
----------

[HttpFoundation] Fix unprepared BinaryFileResponse sends empty file

| Q             | A
| ------------- | ---
| Branch?       | 2.8
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes, with the exception of preexisting, unrelated failures
| Fixed tickets | #28237
| License       | MIT
| Doc PR        |

When you call `BinaryFileResponse#sendContent()` without first calling `prepare()` the response is sent but the contents are empty. `prepare()` properly initializes the `$maxlen` and `$offset` properties. However, `sendContent()` doesn't do any sanity checking, and so, uses the uninitialized properties. This causes `stream_copy_to_stream()` to copy empty contents and the file that is sent, to contain nothing.

This change initializes the properties at definition instead of in `prepare()`.

> Additionally:
> - Bug fixes must be submitted against the lowest branch where they apply

~I'm not sure how early this bug exists, or how far back to go. I'll check to see if 2.7 and 2.8 are affected and report back.~

Commits
-------

dba8687 Instantiate $offset and $maxlen at definition
This was referenced Aug 27, 2018
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