Skip to content
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

fix handling of + in image names, added some functional tests #1391

Merged
merged 1 commit into from
Oct 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[*.yml]
indent_size = 2
3 changes: 3 additions & 0 deletions .github/workflows/php-cs-fixer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ name: PHP-CS-Fixer
on:
pull_request:
push:
branches:
- 1.x
- 2.x

jobs:
php-cs-fixer:
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/phpunit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ name: PHPUnit
on:
pull_request:
push:
branches:
- 1.x
- 2.x

jobs:
phpunit:
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ for a given releases. Unreleased, upcoming changes will be updated here periodic
- Fix special characters encoding in URL path ([dbalabka](https://github.com/dbalabka))
- Update imagine/imagine dependency to 1.1 ([maximgubar](https://github.com/maximgubar))
- Only use actual path without any query parameters from the url ([maximgubar](https://github.com/maximgubar))
See also UPGRADE.md - if you used URLs with domains to get your images, you will need to adjust.
- __\[Dependency Injection\]__ Add aliases for data and filter manager ([fpaterno](https://github.com/fpaterno))
- Use Autorotate Filter from Imagine library ([franmomu](https://github.com/franmomu))
- Fix Mime deprecations for Symfony 4 ([franmomu](https://github.com/franmomu))
Expand Down
6 changes: 4 additions & 2 deletions Imagine/Cache/Helper/PathHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ class PathHelper
{
public static function filePathToUrlPath(string $path): string
{
// this is not exactly the same as what symfony does in UrlGenerator::doGenerate where it strtr a bunch of encodings back to unencoded
// however, as we need to rawurldecode anyways, it should not hurt
return implode('/', array_map('rawurlencode', explode('/', $path)));
}

public static function urlPathToFilePath(string $url): string
{
// used urldecode instead of rawurlencode for BC safety to support "+" in URL
Copy link
Member Author

@dbu dbu Oct 5, 2021

Choose a reason for hiding this comment

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

this did the opposite of what was intended: if there is a + in the filename, we would end up with instead.

Copy link
Contributor

Choose a reason for hiding this comment

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

@dbu thanks for this fix. I've missed this fact in #1162

Copy link
Member Author

Choose a reason for hiding this comment

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

no worries, it is quite confusing what is going on, and the encoding the the symfony route generator does is ... surprising.

i added some unit and functional tests to help us better understand what is happening.

return urldecode($url);
// revert the rawurlencode that the Symfony UrlGenerator applies to paths
return rawurldecode($url);
}
}
26 changes: 20 additions & 6 deletions Tests/Functional/Controller/ImagineControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,24 +49,38 @@ public function testCouldBeGetFromContainer(): void
$this->assertInstanceOf(ImagineController::class, self::$kernel->getContainer()->get(ImagineController::class));
}

public function testShouldResolvePopulatingCacheFirst(): void
public function provideImageNames(): iterable
{
yield 'regular' => ['image' => 'cats.jpeg', 'urlimage' => 'cats.jpeg'];
yield 'whitespace' => ['image' => 'white cat.jpeg', 'urlimage' => 'white%20cat.jpeg'];
yield 'plus' => ['image' => 'cat+plus.jpeg', 'urlimage' => 'cat%2Bplus.jpeg'];
yield 'questionmark' => ['image' => 'cat?question.jpeg', 'urlimage' => 'cat%3Fquestion.jpeg'];
yield 'hash' => ['image' => 'cat#hash.jpeg', 'urlimage' => 'cat%23hash.jpeg'];
}

/**
* @dataProvider provideImageNames
*
* @param string $image
*/
public function testShouldResolvePopulatingCacheFirst($image, $urlimage): void
{
//guard
$this->assertFileDoesNotExist($this->cacheRoot.'/thumbnail_web_path/images/cats.jpeg');
$this->assertFileDoesNotExist($this->cacheRoot.'/thumbnail_web_path/images/'.$image);

$this->client->request('GET', '/media/cache/resolve/thumbnail_web_path/images/cats.jpeg');
$this->client->request('GET', '/media/cache/resolve/thumbnail_web_path/images/'.$urlimage);

$response = $this->client->getResponse();

$this->assertInstanceOf(RedirectResponse::class, $response);
$this->assertSame(302, $response->getStatusCode());
$this->assertSame('http://localhost/media/cache/thumbnail_web_path/images/cats.jpeg', $response->getTargetUrl());
$this->assertSame('http://localhost/media/cache/thumbnail_web_path/images/'.$urlimage, $response->getTargetUrl());

$this->assertFileExists($this->cacheRoot.'/thumbnail_web_path/images/cats.jpeg');
$this->assertFileExists($this->cacheRoot.'/thumbnail_web_path/images/'.$image);

// PHP compiled with WebP support
if ($this->webp_generate) {
$this->assertFileExists($this->cacheRoot.'/thumbnail_web_path/images/cats.jpeg.webp');
$this->assertFileExists($this->cacheRoot.'/thumbnail_web_path/images/'.$image.'.webp');
}
}

Expand Down
50 changes: 50 additions & 0 deletions Tests/Functional/Imagine/Cache/CacheManagerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

/*
* This file is part of the `liip/LiipImagineBundle` project.
*
* (c) https://github.com/liip/LiipImagineBundle/graphs/contributors
*
* For the full copyright and license information, please view the LICENSE.md
* file that was distributed with this source code.
*/

namespace Liip\ImagineBundle\Tests\Functional\Imagine\Cache;

use Liip\ImagineBundle\Imagine\Cache\CacheManager;
use Liip\ImagineBundle\Tests\Functional\AbstractWebTestCase;

/**
* @covers \Liip\ImagineBundle\Imagine\Cache\CacheManager
*/
class CacheManagerTest extends AbstractWebTestCase
{
public function providePaths(): iterable
{
yield 'querystring' => [
'path' => 'path?v51',
'expectedUrl' => 'path%3Fv51',
];

yield 'plus' => [
'path' => 'path+x.jpg',
'expectedUrl' => 'path+x.jpg',
];
}

/**
* @dataProvider providePaths
*/
public function testGetAsService($path, $expectedUrl): void
{
$this->createClient();

/** @var CacheManager $manager */
$manager = self::$kernel->getContainer()->get('liip_imagine.cache.manager');

$this->assertSame(
'http://localhost/media/cache/resolve/thumbnail_web_path/'.$expectedUrl,
$manager->generateUrl($path, 'thumbnail_web_path')
);
}
}
Binary file added Tests/Functional/app/public/images/cat#hash.jpeg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Tests/Functional/app/public/images/cat+plus.jpeg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ given release.
## [2.2.0](https://github.com/liip/LiipImagineBundle/blob/2.2.0/CHANGELOG.md#unreleased)

*Released on* 2019-04-10 *and assigned* [`2.2.0`](https://github.com/liip/LiipImagineBundle/releases/tag/2.2.0) *tag \([view verbose changelog](https://github.com/liip/LiipImagineBundle/compare/2.0.0...2.2.0)\).*
- Until this version, it was possible to pass any URL with domain to the ImagineController and, if the StreamLoader was
used, have your application download images from anywhere and store them locally. In 2.2.0, this security issue has
been fixed. If you relied on this, you need to download images to a location that can be accessed by your configured
loader. If everything comes from the same domain, you could use the StreamLoader with that domain configured as prefix.
- __[Deprecated]__ Constructing `FileSystemLoader`, `FlysystemLoader`, `SimpleMimeTypeGuesser` and `DataManager` with
`\Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface` and
`\Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesserInterface` have been deprecated for Symfony 4.3+ in
Expand Down