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;
 }
示例#4
0
 /**
  * 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);
        }
    }