diff --git a/judge/judgedaemon.main.php b/judge/judgedaemon.main.php index ae63c1dfd47..41eb08be411 100644 --- a/judge/judgedaemon.main.php +++ b/judge/judgedaemon.main.php @@ -16,6 +16,32 @@ $endpoints = []; $domjudge_config = []; +function dj_getopt(string $short_options, array $long_options = []): array +{ + global $argv; + define('GETOPT_REGEX', "/^([a-zA-Z0-9]:{0,2})*$/"); + if (preg_match(GETOPT_REGEX, $short_options) !== 1) { + echo "Error: short options format specified is invalid.\n"; + usage(); + } + $options = getopt($short_options, $long_options); + if ($options===false || !is_array($argv)) { + echo "Error: parsing options failed.\nPlease check: `register_argc_arg` in php.ini.\n"; + usage(); + } + $unknown = false; + foreach (array_slice($argv, 1) as $arg) { + if (str_starts_with($arg, '-') && !array_key_exists(ltrim($arg, '-'), $options)) { + echo "Error: Unknown option: $arg\n"; + $unknown = true; + } + } + if ($unknown) { + usage(); + } + return $options; +} + function judging_directory(string $workdirpath, array $judgeTask) : string { if (filter_var($judgeTask['submitid'], FILTER_VALIDATE_INT) === false || @@ -487,12 +513,7 @@ function fetch_executable_internal( return [$execrunpath, null, null]; } -$options = getopt("dv:n:hVe:j:t:", ["diskspace-error"]); -// FIXME: getopt doesn't return FALSE on parse failure as documented! -if ($options===false) { - echo "Error: parsing options failed.\n"; - usage(); -} +$options = dj_getopt("dv:n:hVe:j:t:", ["diskspace-error"]); if (isset($options['v'])) { $options['verbose'] = $options['v']; }