Skip to content

Accept SVG item icon uploads again - #1612

Merged
KodeStar merged 3 commits into
2.xfrom
fix/svg-icon-upload
Oct 19, 2026
Merged

KodeStar merged 3 commits into
2.xfrom
fix/svg-icon-upload

Conversation

@KodeStar

@KodeStar KodeStar commented Oct 18, 2026 •

Copy link
Copy Markdown
Member

Fixes the second half of #1609: uploading an SVG icon on the add/edit item form fails with "The file field must be an image."

Why

Since the Laravel 11+ upgrade, the bare image validation rule excludes SVG unless allow_svg is passed. The item form already runs uploaded SVGs through enshrined/svg-sanitize, so it can accept them safely.

What

  • ItemController::storelogic validates file with image:allow_svg.
  • The sanitizer now runs when the detected MIME type is SVG, not when the client file name ends in .svg. Laravel validates and names the stored file from the detected type, so going by the file name would let an SVG uploaded as icon.png pass validation and be stored as an unsanitized .svg.
  • The upload and icon URL paths share one sanitizeSvg() helper. It rejects SVGs the sanitizer cannot parse, instead of storing an empty icon. Its script check is now case-insensitive and matches tags with attributes.
  • Tag and user avatar uploads do not sanitize SVG, so they keep the stricter rule.

Follow-up, not in this PR: SettingsController and Setting::getInput still decide whether to sanitize from the client file name.

Tests

New tests/Feature/ItemIconUploadTest.php:

  • An SVG upload is accepted and stored with <script> and onload stripped, whether it is named .svg or .png. The .png case fails if the sanitizer goes by the client file name.
  • A malformed SVG is rejected.
  • A non-image upload is still rejected.

php artisan test is green (167 passed, 1 skipped). I also verified it manually against the lscr.io/linuxserver/heimdall:2.8.3 image: the upload is rejected before the patch and saved after it.

The "Icon could not be downloaded" half of #1609 did not reproduce, either locally or in the 2.8.3 container. It looks environmental, so I've asked the reporter for logs on the issue.

Since the Laravel 11+ upgrade the bare "image" validation rule rejects
SVG files, so uploading an SVG icon on the add/edit item form failed with
"The file field must be an image." The form already sanitizes SVG uploads,
so the rule now uses image:allow_svg.

Validation and the stored file name both use the detected MIME type, while
the sanitizer only ran when the client file name ended in .svg. With SVGs
allowed, an SVG uploaded as icon.png would have been stored as .svg
unsanitized, so sanitization now also runs when the detected type is SVG.

Tag and user avatar uploads do not sanitize SVG and keep the stricter rule.

Refs #1609
Validation and store() both name the file from guessExtension(), so the
client extension check added nothing. Fold the two SVG upload tests into
a data provider, move shared setup into setUp(), and clean up temp files.
Share one sanitizeSvg() helper between the upload and icon URL paths.
It rejects SVGs the sanitizer cannot parse, and its script check now
catches any case and attributes.
@KodeStar
KodeStar merged commit 966c395 into 2.x Oct 19, 2026
1 check passed
@LinuxServer-CI LinuxServer-CI moved this from PRs to Done in Issue & PR Tracker Oct 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

2 participants