public function testRealConfig() { \asm\core\Config::init('myconfig.ini'); $webRoot = \asm\core\Config::get('roots', 'web'); // hack \asm\core\Config::init(\asm\utils\Filesystem::combinePaths($webRoot, "core/config.ini"), \asm\utils\Filesystem::combinePaths($webRoot, "core/internal.ini")); }
public function testRealPath() { $this->assertNotFalse(Filesystem::realPath(self::TEST_DIRECTORY)); $this->assertNotFalse(Filesystem::realPath(self::TEST_DIRECTORY . "/a.txt")); $this->assertNotFalse(Filesystem::realPath(self::TEST_DIRECTORY . "/nonexistent.txt")); $this->assertFalse(Filesystem::realPath(self::TEST_DIRECTORY . "/nonexistent/nonexistent.txt")); $this->assertSame(Filesystem::combinePaths(realpath('.'), 'text'), Filesystem::realPath('text')); }
protected function body() { $plugins = Repositories::getRepository(Repositories::Plugin)->findAll(); $errors = []; foreach ($plugins as $plugin) { /** @var $plugin \Plugin */ $dbPhpFile = $plugin->getMainfile(); $dbDescription = $plugin->getDescription(); $dbIdentifier = $plugin->getIdentifier(); $pluginDirectory = $this->getMainDirectory($dbPhpFile); if ($pluginDirectory === false) { $errors[] = $plugin->getName() . ": " . Language::get(StringID::ReloadManifests_InvalidFolder); continue; } $manifestFile = Filesystem::combinePaths(Config::get('paths', 'plugins'), $pluginDirectory, "manifest.xml"); $xml = new \DOMDocument(); $success = $xml->load(realpath($manifestFile)); if ($success === false) { $errors[] = $plugin->getName() . ": " . Language::get(StringID::ReloadManifests_MalformedXmlOrFileMissing); continue; } $fileDescription = $xml->getElementsByTagName('description')->item(0); $fileArguments = $xml->getElementsByTagName('argument'); $fileIdentifier = $xml->getElementsByTagName('identifier')->item(0); $fileArgumentsArray = []; for ($i = 0; $i < $fileArguments->length; $i++) { $fileArgumentsArray[] = trim($fileArguments->item($i)->nodeValue); } $fileArgumentsString = implode(';', $fileArgumentsArray); if ($dbDescription !== trim($fileDescription->nodeValue)) { $errors[] = $plugin->getName() . ": " . Language::get(StringID::ReloadManifests_DescriptionMismatch); $plugin->setDescription(trim($fileDescription->nodeValue)); Repositories::persist($plugin); } if ($dbIdentifier !== trim($fileIdentifier->nodeValue)) { $errors[] = $plugin->getName() . ": " . Language::get(StringID::ReloadManifests_IdentifierMismatch); $plugin->setIdentifier(trim($fileIdentifier->nodeValue)); Repositories::persist($plugin); } if ($plugin->getConfig() !== $fileArgumentsString) { $errors[] = $plugin->getName() . ": " . Language::get(StringID::ReloadManifests_ArgumentsMismatch); $plugin->setConfig($fileArgumentsString); Repositories::persist($plugin); } } Repositories::flushAll(); if (count($errors) === 0) { $this->addOutput("text", Language::get(StringID::ReloadManifests_DatabaseCorrespondsToManifests)); } else { $this->addOutput("text", implode('<br>', $errors)); } return true; }
protected function body() { if (!$this->userHasPrivileges(User::pluginsRemove)) { return false; } if (!$this->isInputValid(array('id' => 'isIndex'))) { return false; } $id = $this->getParams('id'); /** * @var $plugin \Plugin */ $plugin = Repositories::findEntity(Repositories::Plugin, $id); $pluginFolder = Filesystem::combinePaths(Config::get('paths', 'plugins'), $plugin->getName()); if (!Filesystem::removeDir($pluginFolder)) { return $this->death(StringID::FileSystemError); } RemovalManager::deletePluginById($id); return true; }
function run($array) { $zipFile = $array[0]; if (count($array) !== 2) { throw new InvalidArgumentException("This must receive 2 parameters in the array exactly."); } $launcher = new \asm\core\JavaLauncher(); $pluginResults = ""; $response = null; $error = $launcher->launch(Filesystem::combinePaths(CheckerRunner::$xmlCheckRoot, "/files/plugins/XML XQuery/XQueryPlugin.jar"), array($zipFile, $array[1]), $responseString); if (!$error) { if (isset($responseString)) { try { $response = \asm\plugin\PluginResponse::fromXmlString($responseString); } catch (Exception $ex) { $response = \asm\plugin\PluginResponse::createError('Internal error. Plugin did not supply valid response XML and this error occured: ' . $ex->getMessage() . '. Plugin instead supplied this response string: ' . $responseString); } } } else { $response = \asm\plugin\PluginResponse::createError('Plugin cannot be launched (' . $error . ').'); } return $response; }
/** * Unpack ZIP archive to specified folder. * If it contains only a single directory and nothing else, its contents are extracted instead of the entire ZIP file. This also happens if the only other directory is the "__MACOSX" metadata folder that Macintosh operating systems add to generated ZIP files. * * This function is a security vulnerability. Possible attacks include a very large ZIP file, such as a ZIP bomb, or putting in a file with a relative path such as '../etc/passwd'. * * * @param string $archive source archive path * @param string $destination destination folder path * @param [out]string $errorMessage why did the extraction fail? * @return true on success */ public static function unzip($archive, $destination, &$errorMessage = null) { $zip = new ZipArchive(); $errorCode = $zip->open($archive); if ($errorCode !== true) { $errorMessage = "could not open ZIP file (error code " . $errorCode . ")"; return false; } // Otherwise, this is a normal ZIP file. if (!$zip->extractTo($destination)) { $zip->close(); $errorMessage = "extraction failed"; return false; } $zip->close(); // Now, we'll check if the ZIP file contains only a single folder. If so, // then we'll copy its contests to the root temporary folder, then remove the original folder. $files = scandir($destination); if ($files === false) { $errorMessage = "scanning the temporary directory failed"; return false; } // On Linux, scandir returns the "." and ".." pseudofolders we are not interested in $files = array_diff($files, [".", ".."]); // For ZIP files generated on Mac OS X, we are not interested in the metadata folder. $files = array_diff($files, ["__MACOSX"]); if (count($files) === 0) { $errorMessage = "the ZIP file is empty"; return false; } elseif (count($files) === 1) { // We renumber the remaining file/directory so that it is at index 0. It might not have been because of the subtraction of "." and ".." $files = array_values($files); $soleDirectory = Filesystem::combinePaths($destination, $files[0]); if (is_dir($soleDirectory)) { if (Filesystem::copyIntoDirectory($soleDirectory, $destination)) { Filesystem::removeDir($soleDirectory); return true; } else { $errorMessage = "the ZIP file contained a single directory, but copying its contents to temporary directory failed"; return false; } } } return true; }
/** * Resolves supplied partial path using supplied base. * @param string $parent base for @c $child * @param string $child partial path to be resolved * @return string absolute path of @c $child appended to @c $parent with * OS-dependent directory separators replaced by UNIX-style slashes (or * @throws Exception when the combined paths don't point to an actual file on the filesystem */ private function resolvePath($parent, $child) { $realPath = realpath(Filesystem::combinePaths($parent, $child)); if ($realPath !== false) { $realPath = str_replace('\\', '/', $realPath); return is_dir($realPath) ? $realPath . '/' : $realPath; } else { throw new Exception("The parent path '{$parent}' and the child path '{$child}' combined do not point to any file on the filesystem. Perhaps your internal.ini file is wrong?'"); } }
/** * Attempts to find an XML and an XSL filename in the given folder and adds an error if it cannot find them. * @param $fromWhere string directory from where to load the files * @param $xmlFile string The found XML filename. * @param $xslFile string The found XSL filename. */ private function loadFiles($fromWhere, &$xmlFile, &$xslFile) { $xmlFile = false; $xslFile = false; $files = \asm\utils\Filesystem::getFiles($fromWhere); foreach ($files as $file) { if (Utils::endsWith(strtolower($file), ".xml")) { if ($xmlFile === false) { $xmlFile = \asm\utils\Filesystem::combinePaths($fromWhere, $file); } else { $this->addError("There are two or more .xml files in your submission. There must only be one."); } } if (Utils::endsWith(strtolower($file), ".xsl")) { if ($xslFile === false) { $xslFile = \asm\utils\Filesystem::combinePaths($fromWhere, $file); } else { $this->addError("There are two or more .xsl files in your submission. There must only be one."); } } } if ($xmlFile === false) { $this->addError("Your submission must contain an XML file ending with '.xml'."); } if ($xslFile === false) { $this->addError("Your submission must contain an XSL file ending with '.xsl'."); } }
private function runSchemaTest($zipFile, $fulfillment = null, $details = "") { $result = CheckerRunner::runChecker(new XmlSchemaChecker(), Filesystem::combinePaths(CheckerRunner::$testCasesRoot, "SCHEMA", $zipFile), []); CheckerRunner::assert($this, $zipFile, $result, $fulfillment, $details); }
/** * Deletes test with supplied ID (with input & output files). * @param int $id test ID * @return array error properties provided by removalError() or retrievalError(), * or false in case of success */ public static function deleteTestById($id) { /** * @var $test \PluginTest */ $test = Repositories::findEntity(Repositories::PluginTest, $id); $testFolder = Config::get('paths', 'tests'); // Delete input solution file if (is_file(Filesystem::combinePaths($testFolder, $test->getInput()))) { Filesystem::removeFile(Filesystem::combinePaths($testFolder, $test->getInput())); } // Delete plugin test output if (is_file(Filesystem::combinePaths($testFolder, $test->getOutput()))) { Filesystem::removeFile(Filesystem::combinePaths($testFolder, $test->getOutput())); } Repositories::remove($test); return false; }
private function runDtdTest($zipFile, $fulfillment = null, $details = "") { $result = CheckerRunner::runChecker(new Dtd2014Checker(), Filesystem::combinePaths(CheckerRunner::$testCasesRoot, "DTD", $zipFile), [0, 0]); CheckerRunner::assert($this, $zipFile, $result, $fulfillment, $details); }
<?php namespace asm\unittests; use asm\core\Config; use asm\utils\Filesystem; $xmlcheckRoot = "../../www"; require_once $xmlcheckRoot . "/vendor/autoload.php"; Config::init(Filesystem::combinePaths($xmlcheckRoot, "core/config.ini"), Filesystem::combinePaths($xmlcheckRoot, "core/internal.ini")); class CheckerRunner { public static $xmlCheckRoot = "../../www"; public static $testCasesRoot = "../plugins/cases"; /** * @param $checker mixed A class with a run() method * @param $zipFile string The path to the zip file with the test case * @param $arguments array Configuration of the plugin * @return \asm\plugin\PluginResponse */ public static function runChecker($checker, $zipFile, $arguments) { $testResult = $checker->run(array_merge([$zipFile], $arguments)); return $testResult; } /** * @param $testCase PHPUnit_Framework_TestCase * @param $result \asm\plugin\PluginResponse * @param $fulfillment int * @param $details string */ public static function assert($testCase, $filename, $result, $fulfillment = null, $details = "")
private function runXsltTest($zipFile, $templateCount, $fulfillment = null, $details = "") { $result = CheckerRunner::runChecker(new XsltChecker(), Filesystem::combinePaths(CheckerRunner::$testCasesRoot, "XSLT", $zipFile), [$templateCount]); CheckerRunner::assert($this, $zipFile, $result, $fulfillment, $details); }
private function runXPathTest($zipFile, $fulfillment = null, $details = "") { $result = CheckerRunner::runChecker(new XpathChecker(), Filesystem::combinePaths(CheckerRunner::$testCasesRoot, "XPATH", $zipFile), [5]); CheckerRunner::assert($this, $zipFile, $result, $fulfillment, $details); }