Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion webapp/src/Controller/Jury/SubmissionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -920,7 +920,7 @@ public function sourceAction(
$files[$f->getFilename()][$submitId] = [
'rank' => $f->getRank(),
'filename' => $f->getFilename(),
'source' => mb_check_encoding($f->getSourcecode(), 'UTF-8') ? $f->getSourcecode() : "Could not display file as UTF-8, is it binary?",
'source' => Utils::reencodeUtf8($f->getSourcecode()),
];

// Keep track of the single filename within a submission for handling renaming.
Expand Down
18 changes: 18 additions & 0 deletions webapp/src/Service/CheckConfigService.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public function runAll(): array
'php_version' => $this->checkPhpVersion(),
'php_extensions' => $this->checkPhpExtensions(),
'php_settings' => $this->checkPhpSettings(),
'mbstring_settings' => $this->checkMbstringSettings(),
'mysql_settings' => $this->checkMysqlSettings(),
];

Expand Down Expand Up @@ -197,6 +198,23 @@ public function checkPhpSettings(): ConfigCheckItem
);
}

public function checkMbstringSettings(): ConfigCheckItem
{
$this->stopwatch->start(__FUNCTION__);

$desc = "\nFor submission source code displaying, the detect order should at least contain all expected submission encodings:\n";
$desc .= sprintf(" - `mbstring.detect_order` should at least contain `UTF-8` (now set to `%s`).\n", implode(', ', mb_detect_order()));
$desc .= sprintf(" - Supported encodings: `%s`.\n", implode(', ', mb_list_encodings()));
$result = in_array('UTF-8', mb_detect_order()) ? 'O' : 'W';

$this->stopwatch->stop(__FUNCTION__);
return new ConfigCheckItem(
caption: 'PHP multibyte string settings',
result: $result,
desc: $desc
);
}

public function checkMysqlSettings(): ConfigCheckItem
{
$this->stopwatch->start(__FUNCTION__);
Expand Down
4 changes: 2 additions & 2 deletions webapp/src/Twig/TwigExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -892,7 +892,7 @@ public function codeEditor(
HTML;
$rank = $index;
$id = sprintf('editor%s', $rank);
$source = mb_check_encoding($code, 'UTF-8') ? $code : "Could not display file as UTF-8, is it binary?";
$source = Utils::reencodeUtf8($code);
if ($elementToUpdate) {
$extraForEdit = <<<JS
editor.getModel().onDidChangeContent(() => {
Expand Down Expand Up @@ -942,7 +942,7 @@ public function getMonacoModel(SubmissionFile $file): string
}
$this->renderedSources[$file->getSubmitfileid()] = true;

$source = mb_check_encoding($file->getSourcecode(), 'UTF-8') ? $file->getSourcecode() : "Could not display file as UTF-8, is it binary?";
$source = Utils::reencodeUtf8($file->getSourcecode());
return sprintf(
<<<JS
monaco.editor.createModel(
Expand Down
17 changes: 17 additions & 0 deletions webapp/src/Utils/Utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -1053,6 +1053,23 @@ public static function jsonEncode(mixed $data): string
return json_encode($data, JSON_PRESERVE_ZERO_FRACTION | JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR);
}

public static function reencodeUtf8(string $source): string {
$detectOrder = array_unique(array_merge(mb_detect_order(), mb_list_encodings()));
$encoding = mb_detect_encoding($source, $detectOrder, strict: true);
if ($encoding !== false) {
$encoded = $encoding !== 'UTF-8' ? mb_convert_encoding($source, 'UTF-8', $encoding) : $source;
// Some binary files are strictly valid in an encoding but fail to re-encoding correctly.
// A successive strict call to mb_detect_encoding still says it is validly encoded, but rendering the string fails.
// This will filter these files.
$sanity = mb_convert_encoding($encoded, $encoding, 'UTF-8');
if ($source === $sanity) {
return $encoded;
}
}
return "Could not display file as UTF-8.\n"
. "Check the supported PHP mbstring encodings on the `Config checker` page if you did not expect this file to be binary.";
}

/**
* @return array<string, string>
*/
Expand Down
Loading