<commit_before><?php

namespace App\Models;

use App\Models\Utils;

/**
 * Class for PHP Sandbox runtime access
 */
class PHPSandBox {

    /**
     * Available PHP runtime versions
     * 
     * @var array 
     */
    public static $VERSIONS;

    /**
     * Version
     * 
     * @var string 
     */
    private $version = null;

    /**
     * System path
     * 
     * @var string 
     */
    private $systemPath = null;

    /**
     * Source Code
     * 
     * @var string 
     */
    private $sourceCode = null;

    /**
     * Constructor
     * 
     * @param string $version
     * @param string $sourceCode
     */
    public function __construct($version, $sourceCode) {
        $this->setVersion($version);
        $this->setSourceCode($sourceCode);
        $this->validate();
    }

    /**
     * Checks whether given runtime version available
     * 
     * @param string $version
     * @return boolean
     */
    public function isVersion($version) {
        return (in_array($version, array_keys(self::$VERSIONS))) ? true : false;
    }

    /**
     * Executes settings on runtime
     * 
     * @return string
     * @throws Exception
     */
    public function execute() {
        
        $route = IpResolver::route();
        
        if($route){
            return $this->remote($route, $this->getSourceCode(), $this->getVersion());
        }
        
        $checksum = sha1($this->getSourceCode() . $this->getVersion() . time());

        $files = $this->prepareSandbox($checksum);

        $output = $this->getOutput($files);

        $this->clear($files);

        return $output;
    }

    /**
     * Validate settings
     * 
     * @throws Exception
     */
    public function validate() {
        if (!$this->isVersion($this->getVersion())) {
            throw new \Exception('Requested version not avaialble :: ' . $this->getVersion());
        }

        if (!preg_match('/^[<][?]php/', $this->getSourceCode())) {
            $this->setSourceCode("<?php " . $this->getSourceCode());
        }

        $this->setSystemPath(self::$VERSIONS[$this->getVersion()]);
    }

    /**
     * Removing all files
     * 
     * @param array $files
     */
    private function clear($files) {
        $sandbox = $files['sandbox'];

        unset($files['sandbox']);

        foreach ($files as $file) {
            unlink($file);
        }

        rmdir($sandbox);
    }

    /**
     * Preparing sandbox
     * 
     * @param array $checksum
     * @return string
     * @throws \App\Exception\FileCopyException
     */
    private function prepareSandbox($checksum) {

        $files = array('sandbox' => \App::make('app.config.env')->SANDBOX . $checksum);

        $files['php'] = $files['sandbox'] . "/" . $checksum . ".php";
        $files['ini'] = $files['sandbox'] . "/" . $checksum . ".ini";

        // create sandbox path
        mkdir($files['sandbox']);

        //copy default php.ini to sandbox
        if (!copy(sprintf(\App::make('app.config.env')->PHP_SANDBOX_PATH, $this->getVersion()), $files['ini'])) {
            throw new \App\Exception\FileCopyException();
        }

        $ini_settings = "\n" . file_get_contents(\App::make('app.config.env')->INI_FILE) . "\n";
        $ini_settings .= 'open_basedir = "' . $files['sandbox'] . '"' . "\n";

        //adding custom ini settings to temp ini file
        file_put_contents($files['ini'], $ini_settings, FILE_APPEND);

        //replacing empty spaces
        file_put_contents($files['php'], str_replace("\r\n\r\n\r\n", "", $this->getSourceCode()));

        return $files;
    }

    /**
     * Returns output
     * 
     * @param array $files
     * @return string
     */
    private function getOutput($files) {

        $output = shell_exec($this->getSystemPath() . " -c " . $files['ini'] . " " . $files['php']);

        foreach ($files as $file) {
            $output = str_replace($file, "SandBox-Request", $output);
        }

        //clearing up signatures
        $output = str_replace(array("Content-type: text/html", "X-Powered-By: PHP/" .
            $this->getVersion(), "\r\n\r\n\r\n"), "", $output);

        if (preg_match("/^\s*$/", $output)) {
            $output = "No output!";
        }
        return $output;
    }

    /**
     * Returns Version
     * <commit_msg>adding I/O support for sandbox testing<commit_after><?php

namespace App\Models;

use App\Models\Utils;

/**
 * Class for PHP Sandbox runtime access
 */
class PHPSandBox {

    /**
     * Available PHP runtime versions
     * 
     * @var array 
     */
    public static $VERSIONS;

    /**
     * Version
     * 
     * @var string 
     */
    private $version = null;

    /**
     * System path
     * 
     * @var string 
     */
    private $systemPath = null;

    /**
     * Source Code
     * 
     * @var string 
     */
    private $sourceCode = null;

    /**
     * Constructor
     * 
     * @param string $version
     * @param string $sourceCode
     */
    public function __construct($version, $sourceCode) {
        $this->setVersion($version);
        $this->setSourceCode($sourceCode);
        $this->validate();
    }

    /**
     * Checks whether given runtime version available
     * 
     * @param string $version
     * @return boolean
     */
    public function isVersion($version) {
        return (in_array($version, array_keys(self::$VERSIONS))) ? true : false;
    }

    /**
     * Executes settings on runtime
     * 
     * @return string
     * @throws Exception
     */
    public function execute() {
        
        $route = IpResolver::route();
        
        if($route){
            return $this->remote($route, $this->getSourceCode(), $this->getVersion());
        }
        
        $checksum = sha1($this->getSourceCode() . $this->getVersion() . time());

        $files = $this->prepareSandbox($checksum);

        $output = $this->getOutput($files);

        $this->clear($files);

        return $output;
    }

    /**
     * Validate settings
     * 
     * @throws Exception
     */
    public function validate() {
        if (!$this->isVersion($this->getVersion())) {
            throw new \Exception('Requested version not avaialble :: ' . $this->getVersion());
        }

        if (!preg_match('/^[<][?]php/', $this->getSourceCode())) {
            $this->setSourceCode("<?php " . $this->getSourceCode());
        }

        $this->setSystemPath(self::$VERSIONS[$this->getVersion()]);
    }

    /**
     * Removing all files
     * 
     * @param array $files
     */
    private function clear($files) {
        //force delete sandbox folder
        shell_exec("rm -rf {$files['sandbox']}");
    }

    /**
     * Preparing sandbox
     * 
     * @param array $checksum
     * @return string
     * @throws \App\Exception\FileCopyException
     */
    private function prepareSandbox($checksum) {

        $files = array('sandbox' => \App::make('app.config.env')->SANDBOX . $checksum);

        $files['php'] = $files['sandbox'] . "/" . $checksum . ".php";
        $files['ini'] = $files['sandbox'] . "/" . $checksum . ".ini";

        // create sandbox path
        mkdir($files['sandbox']);

        //copy default php.ini to sandbox
        if (!copy(sprintf(\App::make('app.config.env')->PHP_SANDBOX_PATH, $this->getVersion()), $files['ini'])) {
            throw new \App\Exception\FileCopyException();
        }

        $ini_settings = "\n" . file_get_contents(\App::make('app.config.env')->INI_FILE) . "\n";
        $ini_settings .= 'open_basedir = "' . $files['sandbox'] . '"' . "\n";

        //adding custom ini settings to temp ini file
        file_put_contents($files['ini'], $ini_settings, FILE_APPEND);

        //replacing empty spaces
        file_put_contents($files['php'], str_replace("\r\n\r\n\r\n", "", $this->getSourceCode()));
        
        //change directory
        chdir($files['sandbox']);

        return $files;
    }

    /**
     * Returns output
     * 
     * @param array $files
     * @return string
     */
    private function getOutput($files) {

        $output = shell_exec($this->getSystemPath() . " -c " . $files['ini'] . " " . $files['php']);

        foreach ($files as $file) {
            $output = str_replace($file, "SandBox-Request", $output);
        }

        //clearing up signatures
        $output = str_replace(array("Content-type: text/html", "X-Powered-By: PHP/" .
            $this->getVersion(), "\r\n\r\n\r\n"), "", $output);

        if (preg_match("/^\s*$/", $output)) {
            $output = "No output!";
        }
        return $output;
    }

    /**
     * Returns Version
     * 
{'fraction_non_alphanumeric': 0.1697194528170647, 'fraction_numerical': 0.00023185717597959656, 'mean_word_length': 1.9666437414030262, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7358480', 'n_tokens_mistral': 2691, 'n_tokens_neox': 2563, 'n_words': 516}