* Fix issues with brackets in directory names

* Update dependencies
This commit is contained in:
bohwaz 2022-11-15 13:10:52 +01:00
parent 49b4ec839c
commit 97cbdd15c9
4 changed files with 82 additions and 14 deletions

View file

@ -43,6 +43,7 @@ class ErrorManager
*/
const PRODUCTION = 1;
const DEVELOPMENT = 2;
const CLI_DEVELOPMENT = 4;
/**
* Term colors
@ -269,11 +270,22 @@ class ErrorManager
$html_report = null;
if (self::$enabled != self::PRODUCTION || self::$email_errors) {
if (self::$enabled & self::DEVELOPMENT || self::$email_errors) {
$html_report = self::htmlReport($report);
}
if (PHP_SAPI == 'cli' || 0 === strpos($_SERVER['HTTP_USER_AGENT'] ?? '', 'curl/'))
$is_curl = 0 === strpos($_SERVER['HTTP_USER_AGENT'] ?? '', 'curl/');
$is_cli = PHP_SAPI == 'cli';
if (!$is_cli) {
http_response_code(500);
}
if ($is_curl && !headers_sent()) {
header('Content-Type: text/plain; charset=utf-8', true);
}
if (($is_cli || $is_curl) && (self::$enabled & self::DEVELOPMENT || self::$enabled & self::CLI_DEVELOPMENT))
{
foreach ($report->errors as $e)
{
@ -315,7 +327,11 @@ class ErrorManager
}
}
}
else if (self::$enabled == self::PRODUCTION)
else if (($is_cli || $is_curl) && self::$enabled & self::PRODUCTION) {
self::termPrint(' /!\\ An internal server error occurred ', self::RED);
self::termPrint(' Error reference was: ' . $report->context->id, self::YELLOW);
}
else if (self::$enabled & self::PRODUCTION)
{
self::htmlProduction($report);
}
@ -520,7 +536,7 @@ class ErrorManager
'date' => date(DATE_ATOM),
'os' => PHP_OS,
'language' => 'PHP ' . PHP_VERSION,
'environment' => self::$enabled == self::DEVELOPMENT ? 'development' : 'production:' . self::$enabled,
'environment' => self::$enabled & self::DEVELOPMENT ? 'development' : 'production:' . self::$enabled,
'php_sapi' => PHP_SAPI,
'remote_ip' => isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : null,
'http_method' => isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : null,
@ -718,6 +734,8 @@ class ErrorManager
/**
* Enable error manager
* @param integer $type Type of error management (ErrorManager::PRODUCTION or ErrorManager::DEVELOPMENT)
* You can also use ErrorManager::PRODUCTION | ErrorManager::CLI_DEVELOPMENT to get error messages in CLI but still hide errors
* on web front-end.
* @return void
*/
static public function enable($type = self::DEVELOPMENT)
@ -734,9 +752,9 @@ class ErrorManager
ini_set('log_errors', false);
ini_set('html_errors', false);
ini_set('zend.exception_ignore_args', false); // We want to get the args in exceptions (since PHP 7.4)
error_reporting($type == self::DEVELOPMENT ? -1 : E_ALL & ~E_DEPRECATED & ~E_STRICT);
error_reporting($type & self::DEVELOPMENT ? -1 : E_ALL & ~E_DEPRECATED & ~E_STRICT);
if ($type == self::DEVELOPMENT && PHP_SAPI != 'cli')
if ($type & self::DEVELOPMENT && PHP_SAPI != 'cli')
{
self::setHtmlHeader('<!DOCTYPE html><meta charset="utf-8" /><style type="text/css">
body { font-family: sans-serif; } * { margin: 0; padding: 0; }
@ -760,7 +778,7 @@ class ErrorManager
set_error_handler([__CLASS__, 'errorHandler']);
if ($type == self::DEVELOPMENT)
if ($type & self::DEVELOPMENT)
{
self::startTimer('_global');
}

View file

@ -63,6 +63,7 @@ abstract class NextCloud
self::PROP_NC_DDC,
];
protected string $prefix = '';
protected string $root_url;
protected Server $server;
protected AbstractStorage $storage;
@ -326,6 +327,8 @@ abstract class NextCloud
{
$this->requireAuth();
$base_uri = null;
// Find out which route we are using and replace URI
foreach (self::ROUTES as $route => $method) {
if ($method != 'webdav') {
@ -338,6 +341,10 @@ abstract class NextCloud
}
}
if (!$base_uri) {
throw new Exception('Invalid WebDAV URL', 404);
}
// Android app is using "/remote.php/dav/files/user//" as root
// so let's alias that as well
// ownCloud Android is requesting just /dav/files/
@ -345,6 +352,8 @@ abstract class NextCloud
$base_uri = $match[0];
}
$this->server->prefix = $this->prefix;
$this->server->setBaseURI($base_uri);
$this->server->route($uri);
}

View file

@ -92,6 +92,11 @@ class Server
*/
public string $original_uri;
/**
* Prefix, if you want to force some clients inside a path, eg. '/documents/'
*/
public string $prefix = '';
protected AbstractStorage $storage;
public function setStorage(AbstractStorage $storage)
@ -109,6 +114,15 @@ class Server
$this->base_uri = rtrim($uri, '/') . '/';
}
protected function _prefix(string $uri): string
{
if (!$this->prefix) {
return $uri;
}
return rtrim(rtrim($this->prefix, '/') . '/' . ltrim($uri, '/'), '/');
}
protected function html_directory(string $uri, iterable $list): ?string
{
// Not a file: let's serve a directory listing if you are browsing with a web browser
@ -187,6 +201,8 @@ class Server
throw new Exception('We can only delete to infinity', 400);
}
$uri = $this->_prefix($uri);
$this->checkLock($uri);
$this->storage->delete($uri);
@ -233,6 +249,8 @@ class Server
$hash = bin2hex(base64_decode($_SERVER['HTTP_CONTENT_MD5']));
}
$uri = $this->_prefix($uri);
$this->checkLock($uri);
if (!empty($_SERVER['HTTP_IF_MATCH'])) {
@ -271,6 +289,8 @@ class Server
public function http_head(string $uri, array &$props = []): ?string
{
$uri = $this->_prefix($uri);
$requested_props = self::BASIC_PROPERTIES;
$requested_props[] = 'DAV::getetag';
@ -325,6 +345,8 @@ class Server
$props = [];
$this->http_head($uri, $props);
$uri = $this->_prefix($uri);
$is_collection = !empty($props['DAV::resourcetype']) && $props['DAV::resourcetype'] == 'collection';
$out = '';
@ -523,6 +545,8 @@ class Server
protected function _http_copymove(string $uri, string $method): ?string
{
$uri = $this->_prefix($uri);
$destination = $_SERVER['HTTP_DESTINATION'] ?? null;
$depth = $_SERVER['HTTP_DEPTH'] ?? 1;
@ -581,6 +605,7 @@ class Server
throw new Exception('Unsupported body for MKCOL', 415);
}
$uri = $this->_prefix($uri);
$this->storage->mkcol($uri);
http_response_code(201);
@ -656,6 +681,7 @@ class Server
// We only support depth of 0 and 1
$depth = isset($_SERVER['HTTP_DEPTH']) && empty($_SERVER['HTTP_DEPTH']) ? 0 : 1;
$uri = $this->_prefix($uri);
$body = file_get_contents('php://input');
if (false !== strpos($body, '<!DOCTYPE ')) {
@ -756,7 +782,12 @@ class Server
foreach ($items as $uri => $item) {
$e = '<d:response>';
$path = '/' . str_replace('%2F', '/', rawurlencode(trim($this->base_uri . $uri, '/')));
if ($this->prefix) {
$uri = substr($uri, strlen($this->prefix));
}
$uri = trim(rtrim($this->base_uri, '/') . '/' . ltrim($uri, '/'), '/');
$path = '/' . str_replace('%2F', '/', rawurlencode($uri));
if (($item['DAV::resourcetype'] ?? null) == 'collection') {
$path .= '/';
@ -929,6 +960,7 @@ class Server
public function http_proppatch(string $uri): ?string
{
$uri = $this->_prefix($uri);
$this->checkLock($uri);
$body = file_get_contents('php://input');
@ -948,6 +980,7 @@ class Server
public function http_lock(string $uri): ?string
{
$uri = $this->_prefix($uri);
// We don't use this currently, but maybe later?
//$depth = !empty($this->_SERVER['HTTP_DEPTH']) ? 1 : 0;
//$timeout = isset($_SERVER['HTTP_TIMEOUT']) ? explode(',', $_SERVER['HTTP_TIMEOUT']) : [];
@ -1039,6 +1072,7 @@ class Server
public function http_unlock(string $uri): ?string
{
$uri = $this->_prefix($uri);
$token = $this->getLockToken();
if (!$token) {
@ -1169,6 +1203,7 @@ class Server
}
$uri = substr($uri, strlen($this->base_uri));
$uri = $this->_prefix($uri);
return $uri;
}

View file

@ -51,11 +51,11 @@ class Storage extends AbstractStorage
public function list(string $uri, ?array $properties): iterable
{
$dirs = glob($this->users->current()->path . $uri . '/*', \GLOB_ONLYDIR);
$dirs = self::glob($this->users->current()->path . $uri, '/*', \GLOB_ONLYDIR);
$dirs = array_map('basename', $dirs);
natcasesort($dirs);
$files = glob($this->users->current()->path . $uri . '/*');
$files = self::glob($this->users->current()->path . $uri, '/*');
$files = array_map('basename', $files);
$files = array_diff($files, $dirs);
natcasesort($files);
@ -291,7 +291,7 @@ class Storage extends AbstractStorage
}
if (is_dir($target)) {
foreach (glob($target . '/*') as $file) {
foreach (self::glob($target, '/*') as $file) {
$this->delete(substr($file, strlen($this->users->current()->path)));
}
@ -421,12 +421,18 @@ class Storage extends AbstractStorage
return;
}
static protected function glob(string $path, string $pattern = '', int $flags = 0): array
{
$path = preg_replace('/[\*\?\[\]]/', '\\\\$0', $path);
return glob($path . $pattern, $flags);
}
static public function getDirectorySize(string $path): int
{
$total = 0;
$path = rtrim($path, '/');
foreach (glob($path . '/*', GLOB_NOSORT) as $f) {
foreach (self::glob($path, '/*', GLOB_NOSORT) as $f) {
if (is_dir($f)) {
$total += self::getDirectorySize($f);
}
@ -440,7 +446,7 @@ class Storage extends AbstractStorage
static public function deleteDirectory(string $path): void
{
foreach (glob($path . '/*', GLOB_NOSORT) as $f) {
foreach (self::glob($path, '/*', GLOB_NOSORT) as $f) {
if (is_dir($f)) {
self::deleteDirectory($f);
@rmdir($f);
@ -458,7 +464,7 @@ class Storage extends AbstractStorage
$last = 0;
$path = rtrim($path, '/');
foreach (glob($path . '/*', GLOB_NOSORT) as $f) {
foreach (self::glob($path, '/*', GLOB_NOSORT) as $f) {
if (is_dir($f)) {
$m = self::getDirectoryMTime($f);