Skip to content

Commit 6b9c125

Browse files
committed
Added console command to sanitize SVG files
1 parent 2c4f44e commit 6b9c125

File tree

2 files changed

+93
-3
lines changed

2 files changed

+93
-3
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
/*
3+
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
4+
*
5+
* Copyright (C) 2019 - 2025 Jan Böhmer (https://github.com/jbtronics)
6+
*
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU Affero General Public License as published
9+
* by the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU Affero General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Affero General Public License
18+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
19+
*/
20+
21+
declare(strict_types=1);
22+
23+
24+
namespace App\Command\Attachments;
25+
26+
use App\Entity\Attachments\Attachment;
27+
use App\Services\Attachments\AttachmentSubmitHandler;
28+
use Doctrine\ORM\EntityManagerInterface;
29+
use Symfony\Component\Console\Attribute\AsCommand;
30+
use Symfony\Component\Console\Command\Command;
31+
use Symfony\Component\Console\Input\InputInterface;
32+
use Symfony\Component\Console\Output\OutputInterface;
33+
use Symfony\Component\Console\Style\SymfonyStyle;
34+
35+
#[AsCommand('partdb:attachments:sanitize-svg', "Sanitize uploaded SVG files.")]
36+
class SanitizeSVGAttachmentsCommand extends Command
37+
{
38+
public function __construct(private readonly EntityManagerInterface $entityManager, private readonly AttachmentSubmitHandler $attachmentSubmitHandler, ?string $name = null)
39+
{
40+
parent::__construct($name);
41+
}
42+
43+
public function configure(): void
44+
{
45+
$this->setHelp('This command allows to sanitize SVG files uploaded via attachments. This happens automatically since version 1.17.1, this command is intended to be used for older files.');
46+
}
47+
48+
protected function execute(InputInterface $input, OutputInterface $output): int
49+
{
50+
$io = new SymfonyStyle($input, $output);
51+
52+
$io->info('This command will sanitize all uploaded SVG files. This is only required if you have uploaded (untrusted) SVG files before version 1.17.1. If you are running a newer version, you don\'t need to run this command (again).');
53+
if (!$io->confirm('Do you want to continue?', false)) {
54+
$io->success('Command aborted.');
55+
return Command::FAILURE;
56+
}
57+
58+
$io->info('Sanitizing SVG files...');
59+
60+
//Finding all attachments with svg files
61+
$qb = $this->entityManager->createQueryBuilder();
62+
$qb->select('a')
63+
->from(Attachment::class, 'a')
64+
->where('a.internal_path LIKE :pattern ESCAPE \'#\'')
65+
->orWhere('a.original_filename LIKE :pattern ESCAPE \'#\'')
66+
->setParameter('pattern', '%.svg');
67+
68+
$attachments = $qb->getQuery()->getResult();
69+
$io->note('Found '.count($attachments).' attachments with SVG files.');
70+
71+
if (count($attachments) === 0) {
72+
$io->success('No SVG files found.');
73+
return Command::FAILURE;
74+
}
75+
76+
$io->info('Sanitizing SVG files...');
77+
$io->progressStart(count($attachments));
78+
foreach ($attachments as $attachment) {
79+
/** @var Attachment $attachment */
80+
$io->note('Sanitizing attachment '.$attachment->getId().' ('.($attachment->getFilename() ?? '???').')');
81+
$this->attachmentSubmitHandler->sanitizeSVGAttachment($attachment);
82+
$io->progressAdvance();
83+
84+
}
85+
$io->progressFinish();
86+
87+
$io->success('Sanitization finished. All SVG files have been sanitized.');
88+
return Command::SUCCESS;
89+
}
90+
}

src/Services/Attachments/AttachmentSubmitHandler.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ public function handleUpload(Attachment $attachment, ?AttachmentUpload $upload):
215215
$this->moveFile($attachment, $secure_attachment);
216216

217217
//Sanitize the SVG if needed
218-
$this->sanitizeSVGFiles($attachment);
218+
$this->sanitizeSVGAttachment($attachment);
219219

220220
//Rename blacklisted (unsecure) files to a better extension
221221
$this->renameBlacklistedExtensions($attachment);
@@ -503,11 +503,11 @@ public function getMaximumAllowedUploadSize(): int
503503
}
504504

505505
/**
506-
* Sanatizes the given SVG file, if the attachment is an internal SVG file.
506+
* Sanitizes the given SVG file, if the attachment is an internal SVG file.
507507
* @param Attachment $attachment
508508
* @return Attachment
509509
*/
510-
protected function sanitizeSVGFiles(Attachment $attachment): Attachment
510+
public function sanitizeSVGAttachment(Attachment $attachment): Attachment
511511
{
512512
//We can not do anything on builtins or external ressources
513513
if ($attachment->isBuiltIn() || !$attachment->hasInternal()) {

0 commit comments

Comments
 (0)