diff options
author | Roeland Jago Douma <rullzer@users.noreply.github.com> | 2019-12-23 17:42:03 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-12-23 17:42:03 +0300 |
commit | 4261a91f85e0ca38bb2ef02f28b62264a5984612 (patch) | |
tree | 22d149f52a2413a46407998e4f47218412c9b469 /lib | |
parent | a0ceaff6872d8d3e700d27fedfb906f8fe947c13 (diff) | |
parent | b67980b52d1245472b98d1b9048622794e79baf5 (diff) |
Merge pull request #18489 from nextcloud/backport/18433/stable16
[stable16] Use File Node API for more download cases, skip unreadable files
Diffstat (limited to 'lib')
-rw-r--r-- | lib/private/Streamer.php | 53 | ||||
-rw-r--r-- | lib/private/legacy/files.php | 50 |
2 files changed, 70 insertions, 33 deletions
diff --git a/lib/private/Streamer.php b/lib/private/Streamer.php index 51c2c923c23..2443c401c8d 100644 --- a/lib/private/Streamer.php +++ b/lib/private/Streamer.php @@ -24,6 +24,12 @@ namespace OC; +use OC\Files\Filesystem; +use OCP\Files\File; +use OCP\Files\Folder; +use OCP\Files\InvalidPathException; +use OCP\Files\NotFoundException; +use OCP\Files\NotPermittedException; use OCP\IRequest; use ownCloud\TarStreamer\TarStreamer; use ZipStreamer\ZipStreamer; @@ -75,23 +81,25 @@ class Streamer { $this->streamerInstance = new ZipStreamer(['zip64' => PHP_INT_SIZE !== 4]); } } - + /** * Send HTTP headers - * @param string $name + * @param string $name */ public function sendHeaders($name){ $extension = $this->streamerInstance instanceof ZipStreamer ? '.zip' : '.tar'; $fullName = $name . $extension; $this->streamerInstance->sendHeaders($fullName); } - + /** * Stream directory recursively - * @param string $dir - * @param string $internalDir + * + * @throws NotFoundException + * @throws NotPermittedException + * @throws InvalidPathException */ - public function addDirRecursive($dir, $internalDir='') { + public function addDirRecursive(string $dir, string $internalDir = ''): void { $dirname = basename($dir); $rootDir = $internalDir . $dirname; if (!empty($rootDir)) { @@ -101,22 +109,33 @@ class Streamer { // prevent absolute dirs $internalDir = ltrim($internalDir, '/'); - $files= \OC\Files\Filesystem::getDirectoryContent($dir); + $userFolder = \OC::$server->getRootFolder()->get(Filesystem::getRoot()); + /** @var Folder $dirNode */ + $dirNode = $userFolder->get($dir); + $files = $dirNode->getDirectoryListing(); + foreach($files as $file) { - $filename = $file['name']; - $file = $dir . '/' . $filename; - if(\OC\Files\Filesystem::is_file($file)) { - $filesize = \OC\Files\Filesystem::filesize($file); - $fileTime = \OC\Files\Filesystem::filemtime($file); - $fh = \OC\Files\Filesystem::fopen($file, 'r'); - $this->addFileFromStream($fh, $internalDir . $filename, $filesize, $fileTime); + if($file instanceof File) { + try { + $fh = $file->fopen('r'); + } catch (NotPermittedException $e) { + continue; + } + $this->addFileFromStream( + $fh, + $internalDir . $file->getName(), + $file->getSize(), + $file->getMTime() + ); fclose($fh); - }elseif(\OC\Files\Filesystem::is_dir($file)) { - $this->addDirRecursive($file, $internalDir); + } elseif ($file instanceof Folder) { + if($file->isReadable()) { + $this->addDirRecursive($dir . '/' . $file->getName(), $internalDir); + } } } } - + /** * Add a file to the archive at the specified location and file name. * diff --git a/lib/private/legacy/files.php b/lib/private/legacy/files.php index 140c02e77b6..857bcc96103 100644 --- a/lib/private/legacy/files.php +++ b/lib/private/legacy/files.php @@ -180,7 +180,11 @@ class OC_Files { $userFolder = \OC::$server->getRootFolder()->get(\OC\Files\Filesystem::getRoot()); $file = $userFolder->get($file); if($file instanceof \OC\Files\Node\File) { - $fh = $file->fopen('r'); + try { + $fh = $file->fopen('r'); + } catch (\OCP\Files\NotPermittedException $e) { + continue; + } $fileSize = $file->getSize(); $fileTime = $file->getMTime(); } else { @@ -284,30 +288,44 @@ class OC_Files { */ private static function getSingleFile($view, $dir, $name, $params) { $filename = $dir . '/' . $name; - OC_Util::obEnd(); - $view->lockFile($filename, ILockingProvider::LOCK_SHARED); - - $rangeArray = array(); + $file = null; - if (isset($params['range']) && substr($params['range'], 0, 6) === 'bytes=') { - $rangeArray = self::parseHttpRangeHeader(substr($params['range'], 6), - \OC\Files\Filesystem::filesize($filename)); - } - - if (\OC\Files\Filesystem::isReadable($filename)) { - self::sendHeaders($filename, $name, $rangeArray); - } elseif (!\OC\Files\Filesystem::file_exists($filename)) { + try { + $userFolder = \OC::$server->getRootFolder()->get(\OC\Files\Filesystem::getRoot()); + $file = $userFolder->get($filename); + if(!$file instanceof \OC\Files\Node\File || !$file->isReadable()) { + http_response_code(403); + die('403 Forbidden'); + } + $fileSize = $file->getSize(); + } catch (\OCP\Files\NotPermittedException $e) { + http_response_code(403); + die('403 Forbidden'); + } catch (\OCP\Files\InvalidPathException $e) { + http_response_code(403); + die('403 Forbidden'); + } catch (\OCP\Files\NotFoundException $e) { http_response_code(404); $tmpl = new OC_Template('', '404', 'guest'); $tmpl->printPage(); exit(); - } else { - http_response_code(403); - die('403 Forbidden'); } + + OC_Util::obEnd(); + $view->lockFile($filename, ILockingProvider::LOCK_SHARED); + + $rangeArray = array(); + + if (isset($params['range']) && substr($params['range'], 0, 6) === 'bytes=') { + $rangeArray = self::parseHttpRangeHeader(substr($params['range'], 6), $fileSize); + } + + self::sendHeaders($filename, $name, $rangeArray); + if (isset($params['head']) && $params['head']) { return; } + if (!empty($rangeArray)) { try { if (count($rangeArray) == 1) { |