public function testQuotePhpArguments() { $this->assertSame("'hello', 'hi'", ShellUtils::quotePhpArguments(['hello', 'hi'])); $this->assertSame("'hello', array(0 => 'hi', 1 => 'hi2')", ShellUtils::quotePhpArguments(['hello', ['hi', 'hi2']])); $this->assertSame("546", ShellUtils::quotePhpArgument(546)); $this->assertSame("true", ShellUtils::quotePhpArgument(true)); $this->assertSame("false", ShellUtils::quotePhpArgument(false)); $this->assertSame("54.23", ShellUtils::quotePhpArgument(54.23)); $this->assertSame("null", ShellUtils::quotePhpArgument(null)); }
public function launch($file, array $arguments, &$output) { /// Supplied file path must point to JAR archive with defined main class. if (!file_exists($file)) { return 'File ' . $file . ' doesn\'t exist or cannot be read'; } $java = Config::get('bin', 'java'); $arguments = ShellUtils::makeShellArguments($arguments); $output = `"{$java}" -Dfile.encoding=UTF-8 -jar "{$file}" {$arguments}`; return false; }
public function launch($file, array $arguments, &$output) { /// Supplied file path must point to an executable. if (!file_exists($file)) { return 'File doesn\'t exist or cannot be read'; } $file = realpath($file); $arguments = ShellUtils::makeShellArguments($arguments); $output = `"{$file}" {$arguments}`; return false; }
/** * Creates stack trace with custom formatting from supplied exception. * @param Exception $e * @return string stack trace */ protected static function getCustomTrace(Exception $e) { $trace = array(); $index = 0; $defaults = array('file' => null, 'line' => null, 'class' => null, 'function' => null, 'type' => '::', 'args' => array()); foreach ($e->getTrace() as $props) { $props = array_merge($defaults, $props); $location = $props['file'] ? $props['file'] != 'Command line code' ? basename($props['file']) . ':' . $props['line'] : '[command line]' : '[unknown location]'; if ($props['function'] == 'trigger_error' && $props['class'] === null) { $trace[] = "User error triggered ({$location}): {$props['args'][0]}"; } elseif ($props['class'] == 'Utils' && $props['function'] == 'turnErrorToException' || $props['class'] == 'ErrorHandler' && $props['function'] == 'handleException' || $props['class'] == 'ErrorHandler' && $props['function'] == 'handleError') { continue; } else { $arguments = ShellUtils::quotePhpArguments($props['args']); $function = $props['function'] ? "{$props['function']}({$arguments})" : ''; $caller = $function && $props['class'] ? $props['class'] : ''; $call = $caller ? $props['type'] : ''; $trace[] = "#{$index} {$location} {$caller}{$call}{$function}"; ++$index; } } return implode("\n", $trace); }
/** * Performs the function of this script. */ protected function body() { if (!$this->userHasPrivileges(User::assignmentsSubmit)) { return; } if (!$this->isInputValid(array('assignmentId' => 'isIndex'))) { return; } $userId = User::instance()->getId(); $assignmentId = $this->getParams('assignmentId'); /** * @var $assignment \Assignment */ $assignment = Repositories::getEntityManager()->find('Assignment', $assignmentId); $query = "SELECT s, a FROM Subscription s, Assignment a WHERE s.group = a.group AND s.user = "******" AND a.id = " . $assignmentId; /** * @var $result \Subscription[] */ $result = Repositories::getEntityManager()->createQuery($query)->getResult(); if (count($result) === 0) { $this->stop(Language::get(StringID::HackerError)); return; } if ($result[0]->getStatus() == \Subscription::STATUS_REQUESTED) { $this->stop(Language::get(StringID::SubscriptionNotYetAccepted)); return; } $submissionsFolder = Config::get('paths', 'submissions'); $file = date('Y-m-d_H-i-s_') . $userId . '_' . StringUtils::randomString(10) . '.zip'; if (!$this->saveUploadedFile('submission', $submissionsFolder . $file)) { return; } // Create submission $newSubmission = new \Submission(); $newSubmission->setAssignment($assignment); $newSubmission->setSubmissionFile($file); $newSubmission->setUser(User::instance()->getEntity()); $newSubmission->setDate(new \DateTime()); // Put into database Repositories::persistAndFlush($newSubmission); // Launch plugin, or set full success if not connected to any plugin if ($assignment->getProblem()->getPlugin() === null) { $newSubmission->setSuccess(100); $newSubmission->setInfo(Language::get(StringID::NoPluginUsed)); $previousSubmissions = Repositories::makeDqlQuery("SELECT s FROM \\Submission s WHERE s.user = :sameUser AND s.assignment = :sameAssignment AND s.status != 'graded' AND s.status != 'deleted'")->setParameter('sameUser', User::instance()->getEntity()->getId())->setParameter('sameAssignment', $assignment->getId())->getResult(); foreach ($previousSubmissions as $previousSubmission) { $previousSubmission->setStatus(\Submission::STATUS_NORMAL); Repositories::getEntityManager()->persist($previousSubmission); } $newSubmission->setStatus(\Submission::STATUS_LATEST); Repositories::getEntityManager()->persist($newSubmission); Repositories::flushAll(); } else { Core::launchPlugin($assignment->getProblem()->getPlugin()->getType(), Config::get('paths', 'plugins') . $assignment->getProblem()->getPlugin()->getMainfile(), $submissionsFolder . $file, false, $newSubmission->getId(), explode(';', $assignment->getProblem()->getConfig())); } // Run checking for plagiarism $similarityJar = Config::get('paths', 'similarity'); if ($similarityJar != null && is_file($similarityJar)) { $arguments = "comparenew"; // Get config file and autoloader file $paths = Config::get('paths'); $vendorAutoload = $paths['composerAutoload']; $java = Config::get('bin', 'java'); $javaArguments = Config::get('bin', 'javaArguments'); $pathToCore = Config::get('paths', 'core'); // This code will be passed, shell-escaped to the PHP CLI $launchCode = <<<LAUNCH_CODE require_once '{$vendorAutoload}'; chdir("{$pathToCore}"); `"{$java}" {$javaArguments} -Dfile.encoding=UTF-8 -jar "{$similarityJar}" {$arguments}`; LAUNCH_CODE; ShellUtils::phpExecInBackground(Config::get('bin', 'phpCli'), $launchCode); } }