|
|
|
@ -33,20 +33,31 @@
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
namespace OC\Files\Storage;
|
|
|
|
|
|
|
|
|
|
use OCP\Files\ForbiddenException;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* for local filestore, we only have to map the paths
|
|
|
|
|
*/
|
|
|
|
|
class Local extends \OC\Files\Storage\Common {
|
|
|
|
|
protected $datadir;
|
|
|
|
|
|
|
|
|
|
protected $dataDirLength;
|
|
|
|
|
|
|
|
|
|
protected $allowSymlinks = false;
|
|
|
|
|
|
|
|
|
|
protected $realDataDir;
|
|
|
|
|
|
|
|
|
|
public function __construct($arguments) {
|
|
|
|
|
if (!isset($arguments['datadir']) || !is_string($arguments['datadir'])) {
|
|
|
|
|
throw new \InvalidArgumentException('No data directory set for local storage');
|
|
|
|
|
}
|
|
|
|
|
$this->datadir = $arguments['datadir'];
|
|
|
|
|
$this->realDataDir = rtrim(realpath($this->datadir), '/') . '/';
|
|
|
|
|
if (substr($this->datadir, -1) !== '/') {
|
|
|
|
|
$this->datadir .= '/';
|
|
|
|
|
}
|
|
|
|
|
$this->dataDirLength = strlen($this->realDataDir);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function __destruct() {
|
|
|
|
@ -337,10 +348,27 @@ class Local extends \OC\Files\Storage\Common {
|
|
|
|
|
*
|
|
|
|
|
* @param string $path
|
|
|
|
|
* @return string
|
|
|
|
|
* @throws ForbiddenException
|
|
|
|
|
*/
|
|
|
|
|
public function getSourcePath($path) {
|
|
|
|
|
$fullPath = $this->datadir . $path;
|
|
|
|
|
return $fullPath;
|
|
|
|
|
if ($this->allowSymlinks || $path === '') {
|
|
|
|
|
return $fullPath;
|
|
|
|
|
}
|
|
|
|
|
$pathToResolve = $fullPath;
|
|
|
|
|
$realPath = realpath($pathToResolve);
|
|
|
|
|
while ($realPath === false) { // for non existing files check the parent directory
|
|
|
|
|
$pathToResolve = dirname($pathToResolve);
|
|
|
|
|
$realPath = realpath($pathToResolve);
|
|
|
|
|
}
|
|
|
|
|
if ($realPath) {
|
|
|
|
|
$realPath = $realPath . '/';
|
|
|
|
|
}
|
|
|
|
|
if (substr($realPath, 0, $this->dataDirLength) === $this->realDataDir) {
|
|
|
|
|
return $fullPath;
|
|
|
|
|
} else {
|
|
|
|
|
throw new ForbiddenException("Following symlinks is not allowed ('$fullPath' -> '$realPath' not inside '{$this->realDataDir}')", false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|