Skip to content

dom-crawler + browser-kit empty file upload error "Path cannot be empty" #49014

Closed
@rudiedirkx

Description

@rudiedirkx

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?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions