Skip to content

Commit 3006ead

Browse files
meisterTnickygerritsen
authored andcommitted
Infer output validator by its presence unless explicitly specified.
1 parent ea727c3 commit 3006ead

File tree

1 file changed

+77
-73
lines changed

1 file changed

+77
-73
lines changed

webapp/src/Service/ImportProblemService.php

Lines changed: 77 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ public function importZippedProblem(
266266
if (!$this->parseYaml($problemYaml, $messages, $validationMode, $propertyAccessor, $problem)) {
267267
return null;
268268
}
269-
if ($validationMode != 'default' && !$this->searchAndAddValidator($zip, $messages, $externalId, $validationMode, $problem)) {
269+
if (!$this->searchAndAddValidator($zip, $messages, $externalId, $validationMode, $problem)) {
270270
return null;
271271
}
272272

@@ -902,89 +902,93 @@ private function searchAndAddValidator(ZipArchive $zip, ?array &$messages, strin
902902
}
903903
}
904904
if (sizeof($validatorFiles) == 0) {
905-
$messages['danger'][] = 'Custom validator specified but not found.';
905+
if ($validationMode === 'default') {
906+
return true;
907+
} else {
908+
$messages['danger'][] = 'Custom validator specified but not found.';
909+
return false;
910+
}
911+
}
912+
913+
// File(s) have to share common directory.
914+
$validatorDir = mb_substr($validatorFiles[0], 0, mb_strrpos($validatorFiles[0], '/')) . '/';
915+
$sameDir = true;
916+
foreach ($validatorFiles as $validatorFile) {
917+
if (!Utils::startsWith($validatorFile, $validatorDir)) {
918+
$sameDir = false;
919+
$messages['warning'][] = sprintf('%s does not start with %s.',
920+
$validatorFile, $validatorDir);
921+
break;
922+
}
923+
}
924+
if (!$sameDir) {
925+
$messages['danger'][] = 'Found multiple custom output validators.';
906926
return false;
907927
} else {
908-
// File(s) have to share common directory.
909-
$validatorDir = mb_substr($validatorFiles[0], 0, mb_strrpos($validatorFiles[0], '/')) . '/';
910-
$sameDir = true;
928+
$tmpzipfiledir = exec("mktemp -d --tmpdir=" .
929+
$this->dj->getDomjudgeTmpDir(),
930+
$dontcare, $retval);
931+
if ($retval != 0) {
932+
throw new ServiceUnavailableHttpException(
933+
null, 'Failed to create temporary directory.'
934+
);
935+
}
936+
chmod($tmpzipfiledir, 0700);
911937
foreach ($validatorFiles as $validatorFile) {
912-
if (!Utils::startsWith($validatorFile, $validatorDir)) {
913-
$sameDir = false;
914-
$messages['warning'][] = sprintf('%s does not start with %s.',
915-
$validatorFile, $validatorDir);
916-
break;
938+
$content = $zip->getFromName($validatorFile);
939+
$filebase = basename($validatorFile);
940+
$newfilename = $tmpzipfiledir . "/" . $filebase;
941+
file_put_contents($newfilename, $content);
942+
if ($filebase === 'build' || $filebase === 'run') {
943+
// Mark special files as executable.
944+
chmod($newfilename, 0755);
917945
}
918946
}
919-
if (!$sameDir) {
920-
$messages['danger'][] = 'Found multiple custom output validators.';
921-
return false;
922-
} else {
923-
$tmpzipfiledir = exec("mktemp -d --tmpdir=" .
924-
$this->dj->getDomjudgeTmpDir(),
925-
$dontcare, $retval);
926-
if ($retval != 0) {
927-
throw new ServiceUnavailableHttpException(
928-
null, 'Failed to create temporary directory.'
929-
);
930-
}
931-
chmod($tmpzipfiledir, 0700);
932-
foreach ($validatorFiles as $validatorFile) {
933-
$content = $zip->getFromName($validatorFile);
934-
$filebase = basename($validatorFile);
935-
$newfilename = $tmpzipfiledir . "/" . $filebase;
936-
file_put_contents($newfilename, $content);
937-
if ($filebase === 'build' || $filebase === 'run') {
938-
// Mark special files as executable.
939-
chmod($newfilename, 0755);
940-
}
941-
}
942947

943-
exec("zip -r -j '$tmpzipfiledir/outputvalidator.zip' '$tmpzipfiledir'",
944-
$dontcare, $retval);
945-
if ($retval != 0) {
946-
throw new ServiceUnavailableHttpException(
947-
null, 'Failed to create ZIP file for output validator.'
948-
);
949-
}
948+
exec("zip -r -j '$tmpzipfiledir/outputvalidator.zip' '$tmpzipfiledir'",
949+
$dontcare, $retval);
950+
if ($retval != 0) {
951+
throw new ServiceUnavailableHttpException(
952+
null, 'Failed to create ZIP file for output validator.'
953+
);
954+
}
950955

951-
$outputValidatorZip = file_get_contents($tmpzipfiledir . '/outputvalidator.zip');
952-
$outputValidatorName = substr($externalId, 0, 20) . '_cmp';
953-
if ($this->em->getRepository(Executable::class)->find($outputValidatorName)) {
954-
// Avoid name clash.
955-
$clashCount = 2;
956-
while ($this->em->getRepository(Executable::class)->find(
957-
$outputValidatorName . '_' . $clashCount)) {
958-
$clashCount++;
959-
}
960-
$outputValidatorName = $outputValidatorName . "_" . $clashCount;
956+
$outputValidatorZip = file_get_contents($tmpzipfiledir . '/outputvalidator.zip');
957+
$outputValidatorName = substr($externalId, 0, 20) . '_cmp';
958+
if ($this->em->getRepository(Executable::class)->find($outputValidatorName)) {
959+
// Avoid name clash.
960+
$clashCount = 2;
961+
while ($this->em->getRepository(Executable::class)->find(
962+
$outputValidatorName . '_' . $clashCount)) {
963+
$clashCount++;
961964
}
965+
$outputValidatorName = $outputValidatorName . "_" . $clashCount;
966+
}
962967

963-
$combinedRunCompare = $validationMode == 'custom interactive';
964-
965-
if (!($tempzipFile = tempnam($this->dj->getDomjudgeTmpDir(), "/executable-"))) {
966-
throw new ServiceUnavailableHttpException(null, 'Failed to create temporary file.');
967-
}
968-
file_put_contents($tempzipFile, $outputValidatorZip);
969-
$zipArchive = new ZipArchive();
970-
$zipArchive->open($tempzipFile, ZipArchive::CREATE);
971-
972-
$executable = new Executable();
973-
$executable
974-
->setExecid($outputValidatorName)
975-
->setImmutableExecutable($this->dj->createImmutableExecutable($zipArchive))
976-
->setDescription(sprintf('output validator for %s', $problem->getName()))
977-
->setType($combinedRunCompare ? 'run' : 'compare');
978-
$this->em->persist($executable);
979-
980-
if ($combinedRunCompare) {
981-
$problem->setRunExecutable($executable);
982-
} else {
983-
$problem->setCompareExecutable($executable);
984-
}
968+
$combinedRunCompare = $validationMode == 'custom interactive';
985969

986-
$messages['info'][] = "Added output validator '$outputValidatorName'.";
970+
if (!($tempzipFile = tempnam($this->dj->getDomjudgeTmpDir(), "/executable-"))) {
971+
throw new ServiceUnavailableHttpException(null, 'Failed to create temporary file.');
987972
}
973+
file_put_contents($tempzipFile, $outputValidatorZip);
974+
$zipArchive = new ZipArchive();
975+
$zipArchive->open($tempzipFile, ZipArchive::CREATE);
976+
977+
$executable = new Executable();
978+
$executable
979+
->setExecid($outputValidatorName)
980+
->setImmutableExecutable($this->dj->createImmutableExecutable($zipArchive))
981+
->setDescription(sprintf('output validator for %s', $problem->getName()))
982+
->setType($combinedRunCompare ? 'run' : 'compare');
983+
$this->em->persist($executable);
984+
985+
if ($combinedRunCompare) {
986+
$problem->setRunExecutable($executable);
987+
} else {
988+
$problem->setCompareExecutable($executable);
989+
}
990+
991+
$messages['info'][] = "Added output validator '$outputValidatorName'.";
988992
}
989993
return true;
990994
}

0 commit comments

Comments
 (0)