From 46626915ef6888c958111b259ae6c0d3729b5198 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 16 Feb 2013 01:30:44 +0100 Subject: [PATCH] Use a parser to read custom mount configuration instead of including the php files --- apps/files_external/lib/config.php | 3 +- lib/arrayparser.php | 189 +++++++++++++++++++++++++++++ lib/files/filesystem.php | 16 +-- 3 files changed, 200 insertions(+), 8 deletions(-) create mode 100644 lib/arrayparser.php diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index 44e668a09c..6ef7f37f58 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -279,13 +279,14 @@ class OC_Mount_Config { * @return array */ private static function readData($isPersonal) { + $parser = new \OC\ArrayParser(); if ($isPersonal) { $file = OC_User::getHome(OCP\User::getUser()).'/mount.php'; } else { $file = OC::$SERVERROOT.'/config/mount.php'; } if (is_file($file)) { - $mountPoints = include $file; + $mountPoints = $parser->parsePHP(file_get_contents($file)); if (is_array($mountPoints)) { return $mountPoints; } diff --git a/lib/arrayparser.php b/lib/arrayparser.php new file mode 100644 index 0000000000..3bb394a516 --- /dev/null +++ b/lib/arrayparser.php @@ -0,0 +1,189 @@ +. + * + */ + +namespace OC; + +class SyntaxException extends \Exception { +} + +class ArrayParser { + const TYPE_NUM = 1; + const TYPE_BOOL = 2; + const TYPE_STRING = 3; + const TYPE_ARRAY = 4; + + function parsePHP($string) { + $string = $this->stripPHPTags($string); + $string = $this->stripAssignAndReturn($string); + return $this->parse($string); + } + + function stripPHPTags($string) { + $string = trim($string); + if (substr($string, 0, 5) === '') { + $string = substr($string, 0, -2); + } + return $string; + } + + function stripAssignAndReturn($string) { + $string = trim($string); + if (substr($string, 0, 6) === 'return') { + $string = substr($string, 6); + } + if (substr($string, 0, 1) === '$') { + list(, $string) = explode('=', $string, 2); + } + return $string; + } + + function parse($string) { + $string = trim($string); + $string = trim($string, ';'); + switch ($this->getType($string)) { + case self::TYPE_NUM: + return $this->parseNum($string); + case self::TYPE_BOOL: + return $this->parseBool($string); + case self::TYPE_STRING: + return $this->parseString($string); + case self::TYPE_ARRAY: + return $this->parseArray($string); + } + return null; + } + + function getType($string) { + $string = strtolower($string); + $first = substr($string, 0, 1); + $last = substr($string, -1, 1); + $arrayFirst = substr($string, 0, 5); + if (($first === '"' or $first === "'") and ($last === '"' or $last === "'")) { + return self::TYPE_STRING; + } elseif ($string === 'false' or $string === 'true') { + return self::TYPE_BOOL; + } elseif ($arrayFirst === 'array' and $last === ')') { + return self::TYPE_ARRAY; + } else { + return self::TYPE_NUM; + } + } + + function parseString($string) { + return substr($string, 1, -1); + } + + function parseNum($string) { + return intval($string); + } + + function parseBool($string) { + $string = strtolower($string); + return $string === 'true'; + } + + function parseArray($string) { + $body = substr($string, 5); + $body = trim($body); + $body = substr($body, 1, -1); + $items = $this->splitArray($body); + $result = array(); + $lastKey = -1; + foreach ($items as $item) { + $item = trim($item); + if ($item) { + if (strpos($item, '=>')) { + list($key, $value) = explode('=>', $item, 2); + $key = $this->parse($key); + $value = $this->parse($value); + } else { + $key = ++$lastKey; + $value = $item; + } + + if (is_numeric($key)) { + $lastKey = $key; + } + $result[$key] = $value; + } + } + return $result; + } + + function splitArray($body) { + $inSingleQuote = false;//keep track if we are inside quotes + $inDoubleQuote = false; + $bracketDepth = 0;//keep track if we are inside brackets + $parts = array(); + $start = 0; + $escaped = false;//keep track if we are after an escape character + $skips = array();//keep track of the escape characters we need to remove from the result + if (substr($body, -1, 1) !== ',') { + $body .= ','; + } + for ($i = 0; $i < strlen($body); $i++) { + $char = substr($body, $i, 1); + if ($char === '\\') { + if ($escaped) { + array_unshift($skips, $i - 1); + } + $escaped = !$escaped; + } else { + if ($char === '"' and !$inSingleQuote) { + if ($escaped) { + array_unshift($skips, $i - 1); + } else { + $inDoubleQuote = !$inDoubleQuote; + } + } elseif ($char === "'" and !$inDoubleQuote) { + if ($escaped) { + array_unshift($skips, $i - 1); + } else { + $inSingleQuote = !$inSingleQuote; + } + } elseif (!$inDoubleQuote and !$inSingleQuote) { + if ($char === '(') { + $bracketDepth++; + } elseif ($char === ')') { + if ($bracketDepth <= 0) { + throw new SyntaxException; + } else { + $bracketDepth--; + } + } elseif ($bracketDepth === 0 and $char === ',') { + $part = substr($body, $start, $i - $start); + foreach ($skips as $skip) { + $part = substr($part, 0, $skip - $start) . substr($part, $skip - $start + 1); + } + $parts[] = $part; + $start = $i + 1; + $skips = array(); + } + } + $escaped = false; + } + } + return $parts; + } +} diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index f453086807..89a9ab2921 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -215,9 +215,11 @@ class Filesystem { if ($user == '') { $user = \OC_User::getUser(); } + $parser = new \OC\ArrayParser(); + // Load system mount points if (is_file(\OC::$SERVERROOT . '/config/mount.php')) { - $mountConfig = include 'config/mount.php'; + $mountConfig = $parser->parsePHP(file_get_contents(\OC::$SERVERROOT . '/config/mount.php')); if (isset($mountConfig['global'])) { foreach ($mountConfig['global'] as $mountPoint => $options) { self::mount($options['class'], $options['options'], $mountPoint); @@ -254,7 +256,7 @@ class Filesystem { $root = \OC_User::getHome($user); self::mount('\OC\Files\Storage\Local', array('datadir' => $root), $user); if (is_file($root . '/mount.php')) { - $mountConfig = include $root . '/mount.php'; + $mountConfig = $parser->parsePHP(file_get_contents($root . '/mount.php')); if (isset($mountConfig['user'][$user])) { foreach ($mountConfig['user'][$user] as $mountPoint => $options) { self::mount($options['class'], $options['options'], $mountPoint); @@ -613,11 +615,11 @@ class Filesystem { } /** - * Get the owner for a file or folder - * - * @param string $path - * @return string - */ + * Get the owner for a file or folder + * + * @param string $path + * @return string + */ public static function getOwner($path) { return self::$defaultInstance->getOwner($path); }