Description
Symfony version(s) affected
6.0.11
Description
Using Symfony's dom-crawler and browser-kit (from Goutte) I load a simple page with a simple form: https://webblocks.nl/_form1.html and submit it without giving a file. I would expect an empty file to be uploaded (like a real browser does), or no file to be uploaded at all, but instead browser-kit crashes because it tries to read the no-file like it's a real file.
I thought it had something to do with the special/nested file input name: files[b]
instead of file
, but they both break! Special/nested file input name in this form: https://webblocks.nl/_form2.html both it breaks the same exact way.
How to reproduce
composer require fabpot/goutte
<?php
require 'vendor/autoload.php';
$goutte = new \Goutte\Client();
$crawler = $goutte->request('GET', 'https://webblocks.nl/_form1.html'); // OR:
// $crawler = $goutte->request('GET', 'https://webblocks.nl/_form2.html');
$form = $crawler->selectButton('Submit it')->form();
$crawler = $goutte->submit($form, [
'values' => [
'text' => 'Oele',
],
]);
Error:
ValueError: Path cannot be empty
From vendor/symfony/mime/Part/DataPart.php:68
:
if (false === $handle = @fopen($path, 'r', false)) {
throw new InvalidArgumentException(sprintf('Unable to open path "%s".', $path));
It doesn't crash on the InvalidArgumentException
, but the ValueError
from fopen
I assume. But that's not the point.
dom-crawler
gives browser-kit
an empty file, because it sees a file input, and the file is never filled, because I only submit values[text]=Oele
I'm using the Goutte client, because it's an easy package, but I assume it works with just dom-crawler
and browser-kit
.
Possible Solution
The best solution would be to do exactly what the browser does: send a non-file. I have no idea how that works. Somewhere along the process browser-kit knows the file is empty:
^ array:1 [▼
"file" => array:5 [▼
"name" => ""
"type" => ""
"tmp_name" => ""
"error" => 4
"size" => 0
]
]
but it still tries to read it etc.
The second best solution would be to just completely ignore the file and not send it at all. dom-crawler's Form::getFiles()
could filter on emptiness.
Additional Context
The full browser-kit Request
just before it all breaks:
^ Symfony\Component\BrowserKit\Request {#686 ▼
#uri: "https://webblocks.nl/_http_server.php"
#method: "POST"
#parameters: array:2 [▼
"op" => "Submit it"
"values" => array:1 [▼
"text" => "Oele"
]
]
#files: array:1 [▼
"file" => array:5 [▼
"name" => ""
"type" => ""
"tmp_name" => ""
"error" => 4
"size" => 0
]
]
#cookies: []
#server: array:4 [▼
"HTTP_USER_AGENT" => "Symfony BrowserKit"
"HTTP_REFERER" => "https://webblocks.nl/_form1.html"
"HTTP_HOST" => "webblocks.nl"
"HTTPS" => true
]
#content: null
}
I feel like I must be doing something wrong, because this is such an obvious bug, but I'm not doing anything weird, just load a form and submit it without a file. Has nobody ever done that? How can this be a bug?