Skip to content

Commit

Permalink
Allow SVG in jury test case visualization
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevinjil committed Feb 28, 2025
1 parent 379abdc commit f9f1a54
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 11 deletions.
30 changes: 20 additions & 10 deletions webapp/src/Controller/Jury/ProblemController.php
Original file line number Diff line number Diff line change
Expand Up @@ -605,16 +605,26 @@ public function testcasesAction(Request $request, int $probId): Response
}
$content = file_get_contents($file->getRealPath());
if ($type === 'image') {
$imageType = Utils::getImageType($content, $error);
if ($imageType === false) {
$this->addFlash('danger', sprintf('image: %s', $error));
return $this->redirectToRoute('jury_problem_testcases', ['probId' => $probId]);
}
$thumb = Utils::getImageThumb($content, $thumbnailSize,
$this->dj->getDomjudgeTmpDir(), $error);
if ($thumb === false) {
$this->addFlash('danger', sprintf('image: %s', $error));
return $this->redirectToRoute('jury_problem_testcases', ['probId' => $probId]);
if (mime_content_type($file->getRealPath()) === 'image/svg+xml') {
$content = Utils::sanitizeSvg($content);
if ($content === false) {
$this->addFlash('danger', sprintf('image: %s', $error));
return $this->redirectToRoute('jury_problem_testcases', ['probId' => $probId]);
}
$thumb = $content;
$imageType = 'svg';
} else {
$imageType = Utils::getImageType($content, $error);
if ($imageType === false) {
$this->addFlash('danger', sprintf('image: %s', $error));
return $this->redirectToRoute('jury_problem_testcases', ['probId' => $probId]);
}
$thumb = Utils::getImageThumb($content, $thumbnailSize,
$this->dj->getDomjudgeTmpDir(), $error);
if ($thumb === false) {
$this->addFlash('danger', sprintf('image: %s', $error));
return $this->redirectToRoute('jury_problem_testcases', ['probId' => $probId]);
}
}

$testcase->setImageType($imageType);
Expand Down
6 changes: 6 additions & 0 deletions webapp/src/Service/DOMJudgeService.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ class DOMJudgeService
'image/svg+xml' => 'svg',
];

final public const EXTENSION_TO_MIMETYPE = [
'png' => 'image/png',
'jpg' => 'image/jpeg',
'svg' => 'image/svg+xml',
];

public function __construct(
protected readonly EntityManagerInterface $em,
protected readonly LoggerInterface $logger,
Expand Down
9 changes: 9 additions & 0 deletions webapp/src/Service/ImportProblemService.php
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,15 @@ public function importZippedProblem(
break;
}
}
// Handle SVG differently, as a lot of the above concepts do not make sense in this context.
$imageFileName = $baseFileName . '.svg';
if (($imageFile = $zip->getFromName($imageFileName)) !== false) {
if (($imageFile = Utils::sanitizeSvg($imageFile)) === false) {
$messages['warning'][] = sprintf("Contents of '%s' is not safe.", $imageFileName);
}
$imageType = 'svg';
$imageThumb = $imageFile;
}

if (str_contains($testInput, "\r")) {
$messages['warning'][] = "Testcase file '$baseFileName.in' contains Windows newlines.";
Expand Down
3 changes: 2 additions & 1 deletion webapp/templates/jury/submission.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,8 @@
<span style="float:right; border: 3px solid #438ec3; margin: 5px; padding: 5px;">
{% set imgUrl = path('jury_problem_testcase_fetch', {'probId': submission.problem.probid, 'rank': run.rank, 'type': 'image'}) %}
<a href="{{ imgUrl }}">
<img src="data:image/{{ run.imageType }};base64,{{ runsOutput[runIdx].image_thumb | base64 }}"/>
{% set EXTENSION_TO_MIMETYPE = constant('App\\Service\\DOMJudgeService::EXTENSION_TO_MIMETYPE') %}
<img src="data:{{ EXTENSION_TO_MIMETYPE[run.imageType] }};base64,{{ runsOutput[runIdx].image_thumb | base64 }}"/>
</a>
</span>
{% endif %}
Expand Down

0 comments on commit f9f1a54

Please sign in to comment.