Skip to content

update thumbnail, allow user to choose output format#3714

Open
kouz75 wants to merge 23 commits into
bolt:6.2from
shirkalab:thumbnail
Open

update thumbnail, allow user to choose output format#3714
kouz75 wants to merge 23 commits into
bolt:6.2from
shirkalab:thumbnail

Conversation

@kouz75
Copy link
Copy Markdown
Contributor

@kouz75 kouz75 commented Apr 28, 2026

Add output format support to thumbnail URLs

  • Add optional format parameter to ThumbnailHelper, ImageExtension, and the thumbnail() Twig function
  • Encode the output format as a filename suffix in the URL (e.g. image.jpg.avif) instead of in the param string
  • Parse the format suffix in ImageController to set Glide's fm parameter and resolve the correct source file
  • Backward compatible: URLs without a format suffix continue to work unchanged

Update thumbnail file path in Twig and filesystem to match image URL structure, allowing Apache/Nginx to serve them directly without any PHP call

@kouz75 kouz75 marked this pull request as ready for review April 28, 2026 09:43
@kouz75 kouz75 marked this pull request as draft April 30, 2026 14:42
@kouz75 kouz75 marked this pull request as ready for review April 30, 2026 14:58
@Vondry
Copy link
Copy Markdown
Contributor

Vondry commented May 4, 2026

As a general question - is there a command that would "warm up" thumbnail cache so that even first user can benefit from fast loading image?

@kouz75
Copy link
Copy Markdown
Contributor Author

kouz75 commented May 4, 2026

There is no command for that yet.
One way to fix this is to add a new command that parses all media files (or the content) and generates their thumbnails. The thumbnail settings can be defined in theme.yaml or passed as parameters to the command.

This command may generate a lot of thumbnails that will never be displayed on the website.

Copy link
Copy Markdown
Member

@bobvandevijver bobvandevijver left a comment

Choose a reason for hiding this comment

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

I will need more time to definitively check this, but here's already my first findings. I also believe that are changes in this PR that are not necessarily needed to fix the main issue (which is fixing the webserver direct file serving).

Comment thread src/Controller/ImageController.php
Comment thread src/Controller/ImageController.php Outdated

$this->parseParameters($paramString);
$urlFilename = $filename;
$sourceFilename = $this->parseFormatFromFilename($filename);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Direct usage of the filename will cause a regression into a security incident (#3661) we had in the past, namely a path traversal. Paths can only be used after a canonicalize call.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The filename is still used directly without sanitation, this needs to be resolved first.

kouz75 and others added 12 commits May 10, 2026 11:39
* Using PathCanonicalize::canonicalize() instead of Symfony's Path::canonicalize() closes a path traversal vulnerability.

* fix rector

* fix BadRequestHttpException
Bumps [systeminformation](https://github.com/sebhildebrandt/systeminformation) from 5.31.1 to 5.31.6.
- [Release notes](https://github.com/sebhildebrandt/systeminformation/releases)
- [Changelog](https://github.com/sebhildebrandt/systeminformation/blob/master/CHANGELOG.md)
- [Commits](sebhildebrandt/systeminformation@v5.31.1...v5.31.6)

---
updated-dependencies:
- dependency-name: systeminformation
  dependency-version: 5.31.6
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Backport the default value from Symfony 7.1+ for easy configuration against Host Header Injection
Copy link
Copy Markdown
Member

@bobvandevijver bobvandevijver left a comment

Choose a reason for hiding this comment

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

Lets target this for 6.2 as it changes the paths. Also, can you enable edits from maintainers? If that was enabled I could have fixed the pipeline issues for you.

Comment thread src/Controller/ImageController.php Outdated

$this->parseParameters($paramString);
$urlFilename = $filename;
$sourceFilename = $this->parseFormatFromFilename($filename);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The filename is still used directly without sanitation, this needs to be resolved first.

Comment thread src/Controller/ImageController.php Outdated
Comment on lines +94 to +101
$ext = mb_strtolower(pathinfo($filename, PATHINFO_EXTENSION));
if ($this->isSupportedFormat($ext) && pathinfo(pathinfo($filename, PATHINFO_FILENAME), PATHINFO_EXTENSION) !== '') {
$this->parameters['fm'] = $ext;

return mb_substr($filename, 0, -(mb_strlen($ext) + 1));
}

return $filename;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If I understand correctly, the goal is to retrieve the last part of the path here. Why not just explode on ., and validate if the match is one of the supported extensions?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm not able to allow maintainers to edit the PR ???
I switch the PR to 6.2 and fix both issues.

@kouz75 kouz75 changed the base branch from 6.1 to 6.2 May 18, 2026 16:12
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR prepares a 6.1.3 release with thumbnail URL/output-format updates plus related security hardening for SVG uploads, filemanager path handling, and trusted host configuration.

Changes:

  • Adds thumbnail output format support by encoding the target format as a filename suffix and parsing it in ImageController.
  • Updates thumbnail filesystem paths to mirror public thumbnail URLs for direct web-server serving.
  • Adds security/release updates: SVG sanitization, trusted hosts configuration, filemanager path canonicalization, dependency/version/changelog updates.

Reviewed changes

Copilot reviewed 15 out of 16 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/Utils/ThumbnailHelper.php Adds optional thumbnail output format suffix and includes default fit/location in generated paths.
src/Twig/ImageExtension.php Exposes the new thumbnail format argument through Twig.
src/Controller/ImageController.php Parses format suffixes, sets Glide format, and saves thumbnails under URL-matching paths.
public/theme/skeleton/partials/_image.twig Uses AVIF thumbnails with explicit quality in the skeleton theme.
src/Controller/Backend/FilemanagerController.php Uses path canonicalization for create/delete filemanager actions.
src/Controller/Backend/Async/UploadController.php Replaces manual SVG script checks with SVG sanitization.
composer.json Adds the SVG sanitizer dependency.
phpstan-baseline.php Updates baseline entries for the renamed SVG sanitizer callback.
config/packages/framework.yaml Enables trusted hosts configuration via environment variable.
.env Documents the trusted hosts environment variable.
yaml-migrations/m_2026-05-14-framework.yaml Adds a config migration for trusted hosts.
src/Version.php Bumps the PHP application version to 6.1.3.
assets/js/version.js Bumps the frontend-generated version to 6.1.3.
package.json Bumps the npm package version to 6.1.3.
package-lock.json Updates a locked transitive npm dependency.
CHANGELOG.md Adds release notes for 6.1.3.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +95 to +105
$parts = explode('.', pathinfo($filename, PATHINFO_BASENAME));

if (count($parts) < 3) {
return $filename;
}

$ext = mb_strtolower(end($parts));

if ($this->isSupportedFormat($ext)) {
$this->parameters['fm'] = $ext;
return mb_substr($filename, 0, -(mb_strlen($ext) + 1));
Comment thread package.json
Comment on lines +237 to +239
file_put_contents($file['tmp_name'], $sanitizedSvg);

return true;
@bobvandevijver
Copy link
Copy Markdown
Member

Okay, so I really wanted to take a real look at this PR and test it locally, but my time has run out working on a stupid failing a11y test (!3730), setting up a fully functional test environment with a complete nginx setup instead of the local symfony server and the recent responsible disclosures. So, rest assured, I haven't forgotten, I'm just lacking some time!

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 this pull request may close these issues.

4 participants