sonata-project / SonataMediaBundle

Symfony SonataMediaBundle
https://docs.sonata-project.org/projects/SonataMediaBundle
MIT License
451 stars 495 forks source link

New media creation fails if filename doesn't contain image extension #2208

Closed sarim closed 2 years ago

sarim commented 3 years ago

Environment

GNU/Linux x86_64 5.10.60.1 PHP 7.4.3

Sonata packages

show

``` $ composer show --latest 'sonata-project/*' # Put the result here. sonata-project/admin-bundle 4.0.1 4.2.2 The missing Symfony Admin Generator sonata-project/block-bundle 4.7.0 4.8.0 Symfony SonataBlockBundle sonata-project/cache 2.2.0 2.2.0 Cache library sonata-project/doctrine-extensions 1.14.0 1.15.0 Doctrine2 behavioral extensions sonata-project/doctrine-orm-admin-bundle 4.0.0 4.1.0 Integrate Doctrine ORM into the SonataAdminBundle sonata-project/exporter 2.8.0 2.9.0 Lightweight Exporter library sonata-project/form-extensions 1.11.0 1.12.1 Symfony form extensions sonata-project/media-bundle 4.0.0-alpha1 4.0.0-alpha1 Symfony SonataMediaBundle sonata-project/twig-extensions 1.9.0 1.9.0 Sonata twig extensions ```

Symfony packages

show

``` $ composer show --latest 'symfony/*' # Put the result here. symfony/asset v5.3.4 v5.3.4 Manages URL generation and versioning of web assets such as CSS s... symfony/browser-kit v5.3.4 v5.3.4 Simulates the behavior of a web browser, allowing you to make req... symfony/cache v5.3.8 v5.3.10 Provides an extended PSR-6, PSR-16 (and tags) implementation symfony/cache-contracts v2.4.0 v2.4.0 Generic abstractions related to caching symfony/config v5.3.4 v5.3.10 Helps you find, load, combine, autofill and validate configuratio... symfony/console v5.3.7 v5.3.10 Eases the creation of beautiful and testable command line interfaces symfony/css-selector v5.3.4 v5.3.4 Converts CSS selectors to XPath expressions symfony/debug-bundle v5.3.4 v5.3.4 Provides a tight integration of the Symfony Debug component into ... symfony/dependency-injection v5.3.8 v5.3.10 Allows you to standardize and centralize the way objects are cons... symfony/deprecation-contracts v2.4.0 v2.4.0 A generic function and convention to trigger deprecation notices symfony/doctrine-bridge v5.3.8 v5.3.8 Provides integration for Doctrine with various Symfony components symfony/dom-crawler v5.3.7 v5.3.7 Eases DOM navigation for HTML and XML documents symfony/dotenv v5.3.8 v5.3.10 Registers environment variables from a .env file symfony/error-handler v5.3.7 v5.3.7 Provides tools to manage errors and ease debugging PHP code symfony/event-dispatcher v5.3.7 v5.3.7 Provides tools that allow your application components to communic... symfony/event-dispatcher-contracts v2.4.0 v2.4.0 Generic abstractions related to dispatching event symfony/expression-language v5.3.7 v5.3.7 Provides an engine that can compile and evaluate expressions symfony/filesystem v5.3.4 v5.3.4 Provides basic utilities for the filesystem symfony/finder v5.3.7 v5.3.7 Finds files and directories via an intuitive fluent interface symfony/flex v1.17.1 v1.17.2 Composer plugin for Symfony symfony/form v5.3.8 v5.3.10 Allows to easily create, process and reuse HTML forms symfony/framework-bundle v5.3.8 v5.3.10 Provides a tight integration between Symfony components and the S... symfony/http-client v5.3.8 v5.3.10 Provides powerful methods to fetch HTTP resources synchronously o... symfony/http-client-contracts v2.4.0 v2.4.0 Generic abstractions related to HTTP clients symfony/http-foundation v5.3.7 v5.3.10 Defines an object-oriented layer for the HTTP specification symfony/http-kernel v5.3.9 v5.3.10 Provides a structured process for converting a Request into a Res... symfony/intl v5.3.8 v5.3.8 Provides a PHP replacement layer for the C intl extension that in... symfony/mailer v5.3.9 v5.3.9 Helps sending emails symfony/maker-bundle v1.34.0 v1.34.1 Symfony Maker helps you create empty commands, controllers, form ... symfony/mime v5.3.8 v5.3.8 Allows manipulating MIME messages symfony/monolog-bridge v5.3.7 v5.3.7 Provides integration for Monolog with various Symfony components symfony/monolog-bundle v3.7.0 v3.7.1 Symfony MonologBundle symfony/notifier v5.3.9 v5.3.9 Sends notifications via one or more channels (email, SMS, ...) symfony/options-resolver v5.3.7 v5.3.7 Provides an improved replacement for the array_replace PHP function symfony/password-hasher v5.3.8 v5.3.8 Provides password hashing utilities symfony/phpunit-bridge v5.3.8 v5.3.10 Provides utilities for PHPUnit, especially user deprecation notic... symfony/polyfill-intl-grapheme v1.23.1 v1.23.1 Symfony polyfill for intl's grapheme_* functions symfony/polyfill-intl-icu v1.23.0 v1.23.0 Symfony polyfill for intl's ICU-related data and classes symfony/polyfill-intl-idn v1.23.0 v1.23.0 Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions symfony/polyfill-intl-normalizer v1.23.0 v1.23.0 Symfony polyfill for intl's Normalizer class and related functions symfony/polyfill-mbstring v1.23.1 v1.23.1 Symfony polyfill for the Mbstring extension symfony/polyfill-php73 v1.23.0 v1.23.0 Symfony polyfill backporting some PHP 7.3+ features to lower PHP ... symfony/polyfill-php80 v1.23.1 v1.23.1 Symfony polyfill backporting some PHP 8.0+ features to lower PHP ... symfony/polyfill-php81 v1.23.0 v1.23.0 Symfony polyfill backporting some PHP 8.1+ features to lower PHP ... symfony/process v5.3.7 v5.3.7 Executes commands in sub-processes symfony/property-access v5.3.8 v5.3.8 Provides functions to read and write from/to an object or array u... symfony/property-info v5.3.8 v5.3.8 Extracts information about PHP class' properties using metadata o... symfony/proxy-manager-bridge v5.3.4 v5.3.4 Provides integration for ProxyManager with various Symfony compon... symfony/routing v5.3.7 v5.3.7 Maps an HTTP request to a set of configuration variables symfony/runtime v5.3.4 v5.3.10 Enables decoupling PHP applications from global state symfony/security-acl v3.2.0 v3.2.0 Symfony Security Component - ACL (Access Control List) symfony/security-bundle v5.3.8 v5.3.8 Provides a tight integration of the Security component into the S... symfony/security-core v5.3.8 v5.3.10 Symfony Security Component - Core Library symfony/security-csrf v5.3.4 v5.3.4 Symfony Security Component - CSRF Library symfony/security-guard v5.3.7 v5.3.7 Symfony Security Component - Guard symfony/security-http v5.3.8 v5.3.10 Symfony Security Component - HTTP Integration symfony/serializer v5.3.8 v5.3.10 Handles serializing and deserializing data structures, including ... symfony/service-contracts v2.4.0 v2.4.0 Generic abstractions related to writing services symfony/stopwatch v5.3.4 v5.3.4 Provides a way to profile code symfony/string v5.3.7 v5.3.10 Provides an object-oriented API to strings and deals with bytes, ... symfony/translation v5.3.9 v5.3.10 Provides tools to internationalize your application symfony/translation-contracts v2.4.0 v2.4.0 Generic abstractions related to translation symfony/twig-bridge v5.3.7 v5.3.7 Provides integration for Twig with various Symfony components symfony/twig-bundle v5.3.4 v5.3.10 Provides a tight integration of Twig into the Symfony full-stack ... symfony/validator v5.3.8 v5.3.10 Provides tools to validate values symfony/var-dumper v5.3.8 v5.3.10 Provides mechanisms for walking through any arbitrary PHP variable symfony/var-exporter v5.3.8 v5.3.8 Allows exporting any serializable PHP data structure to plain PHP... symfony/web-link v5.3.4 v5.3.4 Manages links between resources symfony/web-profiler-bundle v5.3.8 v5.3.8 Provides a development tool that gives detailed information about... symfony/webpack-encore-bundle v1.12.0 v1.12.0 Integration with your Symfony app & Webpack Encore! symfony/yaml v5.3.6 v5.3.6 Loads and dumps YAML files ```

PHP version

$ php -v
# Put the result here.
PHP 7.4.3 (cli) (built: Oct  6 2020 15:47:56) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.3, Copyright (c), by Zend Technologies

Subject

$file= $request->files->get('files')[0];

$media = new Media();
$media->setBinaryContent($file->getPathname());
$media->setName($file->getClientOriginalName());
$media->setContext($context);
$media->setProviderName('sonata.media.provider.image');
$mediaManager->save($media);

Error with Length of either side cannot be 0 or negative, current size is 0x0. This is because the is '/tmp/randomLetters'. If I move the file to '/tmp/random-filename.jpeg' then pass it to media, it works.

Another easy way to reproduce is to use the command.

cp ~/exampleImage.jpeg ~/exampleImage
bin/console sonata:media:add sonata.media.provider.image default ~/exampleImage

I also tried

$media->setContentType($upload->getMimeType());

But that doesn't help.

Steps to reproduce

bin/console sonata:media:add sonata.media.provider.image default ~/exampleImage

Expected results

media save success;

Actual results

Imagine\Exception\InvalidArgumentException:
Length of either side cannot be 0 or negative, current size is 0x0

  at vendor/imagine/imagine/src/Image/Box.php:50
  at Imagine\Image\Box->__construct()
     (vendor/sonata-project/media-bundle/src/Model/Media.php:321)
  at Sonata\MediaBundle\Model\Media->getBox()
     (vendor/sonata-project/media-bundle/src/Resizer/SimpleResizer.php:60)
  at Sonata\MediaBundle\Resizer\SimpleResizer->getBox()
     (vendor/sonata-project/media-bundle/src/Resizer/SimpleResizer.php:52)
  at Sonata\MediaBundle\Resizer\SimpleResizer->resize()
     (vendor/sonata-project/media-bundle/src/Thumbnail/FormatThumbnail.php:111)
  at Sonata\MediaBundle\Thumbnail\FormatThumbnail->generate()
     (vendor/sonata-project/media-bundle/src/Provider/BaseProvider.php:142)
  at Sonata\MediaBundle\Provider\BaseProvider->generateThumbnails()
     (vendor/sonata-project/media-bundle/src/Provider/FileProvider.php:138)
  at Sonata\MediaBundle\Provider\FileProvider->postPersist()
     (vendor/sonata-project/media-bundle/src/Listener/BaseMediaEventSubscriber.php:61)
  at Sonata\MediaBundle\Listener\BaseMediaEventSubscriber->postPersist()
     (vendor/symfony/doctrine-bridge/ContainerAwareEventManager.php:68)
  at Symfony\Bridge\Doctrine\ContainerAwareEventManager->dispatchEvent()
     (vendor/doctrine/orm/lib/Doctrine/ORM/Event/ListenersInvoker.php:99)
  at Doctrine\ORM\Event\ListenersInvoker->invoke()
     (vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1143)
  at Doctrine\ORM\UnitOfWork->executeInserts()
     (vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:408)
  at Doctrine\ORM\UnitOfWork->commit()
     (vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:388)
  at Doctrine\ORM\EntityManager->flush()
     (var/cache/dev/Container2gR4ea5/EntityManager_9a5be93.php:136)
  at Container2gR4ea5\EntityManager_9a5be93->flush()
     (vendor/sonata-project/doctrine-extensions/src/Model/BaseManager.php:117)
  at Sonata\Doctrine\Model\BaseManager->save()
     (src/SK/PCwBundle/Controller/BatchImageAdminController.php:51)
  at SK\PCwBundle\Controller\BatchImageAdminController->uploadAction()
     (vendor/symfony/http-kernel/HttpKernel.php:156)
  at Symfony\Component\HttpKernel\HttpKernel->handleRaw()
     (vendor/symfony/http-kernel/HttpKernel.php:78)
  at Symfony\Component\HttpKernel\HttpKernel->handle()
     (vendor/symfony/http-kernel/Kernel.php:199)
  at Symfony\Component\HttpKernel\Kernel->handle()
     (vendor/symfony/runtime/Runner/Symfony/HttpKernelRunner.php:37)
  at Symfony\Component\Runtime\Runner\Symfony\HttpKernelRunner->run()
     (vendor/autoload_runtime.php:35)
  at require_once('PROJECT_DIR/app/vendor/autoload_runtime.php')
     (public/index.php:5)      
jordisala1991 commented 3 years ago

Did you had the same issue with 3.x?

sarim commented 3 years ago

Did you had the same issue with 3.x?

Yes, just tried, same in v3 too.

jordisala1991 commented 3 years ago

After some testing in #2211 :

I don't know how it worked for 2.x of media-bundle, that version is really old and long time unmaintained. But we can talk about how is implemented on 3.x for the moment.

So, it is normal with the current code that it does not let you upload images without extension, because with the current code you must provide a list of allowed extensions and allowed mimetypes and both of them must match.

What can we do?

  1. The current behavior is confusing because it should give a better error message instead of break in another point, not really related to the problem. We can probably throw some exception is the extensions and the mimetype do not match. Wdyt @VincentLanglet ? Probably this needs to be done directly on 4.x and we can only give a deprecation on 3.x because it could be considered BC break (or we can consider a bug fix, so it is not affected that much by bc breaks).

  2. We can add a new feature to allow any extension for the media provider. That can be done by telling an empty list means: "All extensions allowed". This could also be considered as a bc break because it changes behavior but not sure how many people use an empty list for extension list, because currently it means you won't be able to upload any image really.

~We need to take a better look at all possible ways to upload medias to ensure none of them break after those changes.~ On FileProvider we already throw on doTransform so it should be safe throwing also on ImageProvider

I will take care of the first point, since I am only interested on fixing bugs, but if you want to contribute, feel free to provide a PR for the second point.

VincentLanglet commented 3 years ago

For the second point an empty array could mean no extension when passing false could disable the check (like it works for validation groups and form)

But for now improving the exception seems ok

sarim commented 3 years ago

because with the current code you must provide a list of allowed extensions and allowed mimetypes and both of them must match

As far as I remember the same was true for v2, but it used to work for v2. But lets skip the talk of v2. There is already a media->setContentType function, which does not help. Maybe there should be another $media->setFilename method. Edit: There is already $media->setName method. Maybe the code should try to find extension from name if there is no extension in binaryContent.