Skip to content

Psr17Factory::buildServerRequestFromGlobals() throws TypeError when encountering nested array of file uploads #226

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

Closed
mfb opened this issue Apr 20, 2023 · 5 comments · Fixed by #227

Comments

@mfb
Copy link
Contributor

mfb commented Apr 20, 2023

PHP version: 8.2.5

Description

PHP allows file uploads to be nested in an arbitrarily deep array structure (see example markup below). For requests using this feature, Psr17Factory::buildServerRequestFromGlobals() throws TypeError: Http\Discovery\Psr17Factory::createStreamFromFile(): Argument ($filename) must be of type string, array given, called in /vendor/php-http/discovery/src/Psr17Factory.php on line 271 in Http\Discovery\Psr17Factory->createStreamFromFile() (line 120 of /vendor/php-http/discovery/src/Psr17Factory.php)

How to reproduce
Uploading a file to this script should throw the TypeError:

<pre>
<form method="post" enctype="multipart/form-data">
  <input multiple="multiple" type="file" name="files[upload_0][]">
  <input type="submit" name="submit">
</form>

<?php
use Http\Discovery\Psr17Factory;
require './vendor/autoload.php';
print_r($_FILES);
(new Psr17Factory())->createServerRequestFromGlobals();

Possible Solution

Additional context
Discovered in getsentry/sentry-php#1517

@dbu
Copy link
Contributor

dbu commented Apr 21, 2023

from the stack trace, the problem is at the bottom of the factory:

} elseif (\is_array($value['tmp_name'])) {
and is discovered thanks to strict typing. we should add a recursion there to dig into the array until we get to a string.

@nicolas-grekas
Copy link
Collaborator

Can you please provide a test case and a fix maybe in a PR?

@vjik
Copy link
Contributor

vjik commented Apr 25, 2023

Same problem.

Http\Discovery\Psr17Factory::createStreamFromFile(): Argument #1 ($filename) must be of type string, array given, called in /app/vendor/php-http/discovery/src/Psr17Factory.php on line 271

@mfb
Copy link
Contributor Author

mfb commented Apr 26, 2023

Can you please provide a test case and a fix maybe in a PR?

As far as I can tell, we could simply copy the working logic from guzzlehttp/psr7's ServerRequest class, as there is already a comment mentioning that package and its copyright information.

@nicolas-grekas
Copy link
Collaborator

Fixed in v1.16.0, thanks for the PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants