diff options
Diffstat (limited to 'lib/private')
-rw-r--r-- | lib/private/app.php | 8 | ||||
-rw-r--r-- | lib/private/appconfig.php | 27 | ||||
-rw-r--r-- | lib/private/appframework/app.php | 25 | ||||
-rw-r--r-- | lib/private/connector/sabre/dummygetresponseplugin.php | 18 | ||||
-rw-r--r-- | lib/private/connector/sabre/file.php | 54 | ||||
-rw-r--r-- | lib/private/connector/sabre/quotaplugin.php | 3 | ||||
-rw-r--r-- | lib/private/console/application.php | 2 | ||||
-rw-r--r-- | lib/private/encryption/exceptions/decryptionfailedexception.php | 11 | ||||
-rw-r--r-- | lib/private/encryption/hookmanager.php | 8 | ||||
-rw-r--r-- | lib/private/encryption/keys/storage.php | 14 | ||||
-rw-r--r-- | lib/private/encryption/update.php | 34 | ||||
-rw-r--r-- | lib/private/encryption/util.php | 2 | ||||
-rw-r--r-- | lib/private/files.php | 88 | ||||
-rw-r--r-- | lib/private/files/storage/dav.php | 8 | ||||
-rw-r--r-- | lib/private/files/storage/wrapper/encryption.php | 63 | ||||
-rw-r--r-- | lib/private/files/stream/encryption.php | 18 | ||||
-rw-r--r-- | lib/private/helper.php | 5 | ||||
-rw-r--r-- | lib/private/l10n.php | 11 | ||||
-rw-r--r-- | lib/private/share/mailnotifications.php | 5 | ||||
-rw-r--r-- | lib/private/util.php | 2 |
20 files changed, 287 insertions, 119 deletions
diff --git a/lib/private/app.php b/lib/private/app.php index aec67e6efd6..a4dd513a5d8 100644 --- a/lib/private/app.php +++ b/lib/private/app.php @@ -385,7 +385,13 @@ class OC_App { public static function getAppNavigationEntries($app) { if (is_file(self::getAppPath($app) . '/appinfo/app.php')) { OC::$server->getNavigationManager()->clear(); - require $app . '/appinfo/app.php'; + try { + require $app . '/appinfo/app.php'; + } catch (\OC\Encryption\Exceptions\ModuleAlreadyExistsException $e) { + // FIXME we should avoid getting this exception in first place, + // For now we just catch it, since we don't care about encryption modules + // when trying to find out, whether the app has a navigation entry. + } return OC::$server->getNavigationManager()->getAll(); } return array(); diff --git a/lib/private/appconfig.php b/lib/private/appconfig.php index a2095c571f3..37532616e1e 100644 --- a/lib/private/appconfig.php +++ b/lib/private/appconfig.php @@ -42,13 +42,14 @@ namespace OC; -use \OC\DB\Connection; +use OC\DB\Connection; +use OCP\IAppConfig; /** * This class provides an easy way for apps to store config values in the * database. */ -class AppConfig implements \OCP\IAppConfig { +class AppConfig implements IAppConfig { /** * @var \OC\DB\Connection $conn */ @@ -64,7 +65,7 @@ class AppConfig implements \OCP\IAppConfig { private $apps = null; /** - * @param \OC\DB\Connection $conn + * @param Connection $conn */ public function __construct(Connection $conn) { $this->conn = $conn; @@ -172,27 +173,31 @@ class AppConfig implements \OCP\IAppConfig { } /** - * sets a value in the appconfig + * Sets a value. If the key did not exist before it will be created. * * @param string $app app * @param string $key key * @param string $value value - * - * Sets a value. If the key did not exist before it will be created. + * @return void */ public function setValue($app, $key, $value) { + $inserted = false; // Does the key exist? no: insert, yes: update. if (!$this->hasKey($app, $key)) { - $data = array( + $inserted = (bool) $this->conn->insertIfNotExist('*PREFIX*appconfig', [ 'appid' => $app, 'configkey' => $key, 'configvalue' => $value, - ); - $this->conn->insert('*PREFIX*appconfig', $data); - } else { + ], [ + 'appid', + 'configkey', + ]); + } + + if (!$inserted) { $oldValue = $this->getValue($app, $key); if($oldValue === strval($value)) { - return true; + return; } $data = array( 'configvalue' => $value, diff --git a/lib/private/appframework/app.php b/lib/private/appframework/app.php index ede97180fe2..f6c1e31cddd 100644 --- a/lib/private/appframework/app.php +++ b/lib/private/appframework/app.php @@ -49,19 +49,22 @@ class App { */ public static function buildAppNamespace($appId, $topNamespace='OCA\\') { // first try to parse the app's appinfo/info.xml <namespace> tag - $filePath = OC_App::getAppPath($appId) . '/appinfo/info.xml'; - $loadEntities = libxml_disable_entity_loader(false); - $xml = @simplexml_load_file($filePath); - libxml_disable_entity_loader($loadEntities); - - if ($xml) { - $result = $xml->xpath('/info/namespace'); - if ($result && count($result) > 0) { - // take first namespace result - return $topNamespace . trim((string) $result[0]); + $appPath = OC_App::getAppPath($appId); + if ($appPath !== false) { + $filePath = "$appPath/appinfo/info.xml"; + if (is_file($filePath)) { + $loadEntities = libxml_disable_entity_loader(false); + $xml = @simplexml_load_file($filePath); + libxml_disable_entity_loader($loadEntities); + if ($xml) { + $result = $xml->xpath('/info/namespace'); + if ($result && count($result) > 0) { + // take first namespace result + return $topNamespace . trim((string) $result[0]); + } + } } } - // if the tag is not found, fall back to uppercasing the first letter return $topNamespace . ucfirst($appId); } diff --git a/lib/private/connector/sabre/dummygetresponseplugin.php b/lib/private/connector/sabre/dummygetresponseplugin.php index 7d57f6021fa..6057236b635 100644 --- a/lib/private/connector/sabre/dummygetresponseplugin.php +++ b/lib/private/connector/sabre/dummygetresponseplugin.php @@ -20,6 +20,8 @@ */ namespace OC\Connector\Sabre; +use Sabre\HTTP\ResponseInterface; +use Sabre\HTTP\RequestInterface; /** * Class DummyGetResponsePlugin is a plugin used to not show a "Not implemented" @@ -42,15 +44,25 @@ class DummyGetResponsePlugin extends \Sabre\DAV\ServerPlugin { * @param \Sabre\DAV\Server $server * @return void */ - function initialize(\Sabre\DAV\Server $server) { + function initialize(\Sabre\DAV\Server $server) { $this->server = $server; - $this->server->on('method:GET', [$this,'httpGet'], 200); + $this->server->on('method:GET', [$this, 'httpGet'], 200); } /** + * @param RequestInterface $request + * @param ResponseInterface $response * @return false */ - function httpGet() { + function httpGet(RequestInterface $request, ResponseInterface $response) { + $string = 'This is the WebDAV interface. It can only be accessed by ' . + 'WebDAV clients such as the ownCloud desktop sync client.'; + $stream = fopen('php://memory','r+'); + fwrite($stream, $string); + rewind($stream); + + $response->setBody($stream); + return false; } } diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php index 8ff5577629d..8e4460ef3b5 100644 --- a/lib/private/connector/sabre/file.php +++ b/lib/private/connector/sabre/file.php @@ -99,8 +99,8 @@ class File extends Node implements IFile { return $this->createFileChunked($data); } - list($storage) = $this->fileView->resolvePath($this->path); - $needsPartFile = $this->needsPartFile($storage) && (strlen($this->path) > 1); + list($partStorage) = $this->fileView->resolvePath($this->path); + $needsPartFile = $this->needsPartFile($partStorage) && (strlen($this->path) > 1); if ($needsPartFile) { // mark file as partial while uploading (ignored by the scanner) @@ -110,14 +110,16 @@ class File extends Node implements IFile { $partFilePath = $this->path; } + // the part file and target file might be on a different storage in case of a single file storage (e.g. single file share) + /** @var \OC\Files\Storage\Storage $partStorage */ + list($partStorage, $internalPartPath) = $this->fileView->resolvePath($partFilePath); /** @var \OC\Files\Storage\Storage $storage */ - list($storage, $internalPartPath) = $this->fileView->resolvePath($partFilePath); - list(, $internalPath) = $this->fileView->resolvePath($this->path); + list($storage, $internalPath) = $this->fileView->resolvePath($this->path); try { - $target = $storage->fopen($internalPartPath, 'wb'); + $target = $partStorage->fopen($internalPartPath, 'wb'); if ($target === false) { \OC_Log::write('webdav', '\OC\Files\Filesystem::fopen() failed', \OC_Log::ERROR); - $storage->unlink($internalPartPath); + $partStorage->unlink($internalPartPath); // because we have no clue about the cause we can only throw back a 500/Internal Server Error throw new Exception('Could not write file contents'); } @@ -130,7 +132,7 @@ class File extends Node implements IFile { if (isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['REQUEST_METHOD'] !== 'LOCK') { $expected = $_SERVER['CONTENT_LENGTH']; if ($count != $expected) { - $storage->unlink($internalPartPath); + $partStorage->unlink($internalPartPath); throw new BadRequest('expected filesize ' . $expected . ' got ' . $count); } } @@ -159,14 +161,38 @@ class File extends Node implements IFile { } try { + $view = \OC\Files\Filesystem::getView(); + $run = true; + if ($view) { + $hookPath = $view->getRelativePath($this->fileView->getAbsolutePath($this->path)); + + if (!$exists) { + \OC_Hook::emit(\OC\Files\Filesystem::CLASSNAME, \OC\Files\Filesystem::signal_create, array( + \OC\Files\Filesystem::signal_param_path => $hookPath, + \OC\Files\Filesystem::signal_param_run => &$run, + )); + } else { + \OC_Hook::emit(\OC\Files\Filesystem::CLASSNAME, \OC\Files\Filesystem::signal_update, array( + \OC\Files\Filesystem::signal_param_path => $hookPath, + \OC\Files\Filesystem::signal_param_run => &$run, + )); + } + \OC_Hook::emit(\OC\Files\Filesystem::CLASSNAME, \OC\Files\Filesystem::signal_write, array( + \OC\Files\Filesystem::signal_param_path => $hookPath, + \OC\Files\Filesystem::signal_param_run => &$run, + )); + } + if ($needsPartFile) { // rename to correct path try { - $renameOkay = $storage->rename($internalPartPath, $internalPath); - $fileExists = $storage->file_exists($internalPath); - if ($renameOkay === false || $fileExists === false) { - \OC_Log::write('webdav', '\OC\Files\Filesystem::rename() failed', \OC_Log::ERROR); - $storage->unlink($internalPartPath); + if ($run) { + $renameOkay = $storage->moveFromStorage($partStorage, $internalPartPath, $internalPath); + $fileExists = $storage->file_exists($internalPath); + } + if (!$run || $renameOkay === false || $fileExists === false) { + \OC_Log::write('webdav', 'renaming part file to final file failed', \OC_Log::ERROR); + $partStorage->unlink($internalPartPath); throw new Exception('Could not rename part file to final file'); } } catch (\OCP\Files\LockNotAcquiredException $e) { @@ -176,11 +202,9 @@ class File extends Node implements IFile { } // since we skipped the view we need to scan and emit the hooks ourselves - $storage->getScanner()->scanFile($internalPath); + $partStorage->getScanner()->scanFile($internalPath); - $view = \OC\Files\Filesystem::getView(); if ($view) { - $hookPath = $view->getRelativePath($this->fileView->getAbsolutePath($this->path)); $this->fileView->getUpdater()->propagate($hookPath); if (!$exists) { \OC_Hook::emit(\OC\Files\Filesystem::CLASSNAME, \OC\Files\Filesystem::signal_post_create, array( diff --git a/lib/private/connector/sabre/quotaplugin.php b/lib/private/connector/sabre/quotaplugin.php index 51eab1bae6e..22b687b3508 100644 --- a/lib/private/connector/sabre/quotaplugin.php +++ b/lib/private/connector/sabre/quotaplugin.php @@ -89,6 +89,9 @@ class QuotaPlugin extends \Sabre\DAV\ServerPlugin { $uri = '/' . $uri; } list($parentUri, $newName) = \Sabre\HTTP\URLUtil::splitPath($uri); + if(is_null($parentUri)) { + $parentUri = ''; + } $req = $this->server->httpRequest; if ($req->getHeader('OC-Chunked')) { $info = \OC_FileChunking::decodeName($newName); diff --git a/lib/private/console/application.php b/lib/private/console/application.php index 6d24665e012..f2aacbfc0e6 100644 --- a/lib/private/console/application.php +++ b/lib/private/console/application.php @@ -35,7 +35,7 @@ class Application { if ($this->config->getSystemValue('installed', false)) { if (!\OCP\Util::needUpgrade()) { OC_App::loadApps(); - foreach (OC_App::getAllApps() as $app) { + foreach (\OC::$server->getAppManager()->getInstalledApps() as $app) { $file = OC_App::getAppPath($app) . '/appinfo/register_command.php'; if (file_exists($file)) { require $file; diff --git a/lib/private/encryption/exceptions/decryptionfailedexception.php b/lib/private/encryption/exceptions/decryptionfailedexception.php index 406ae12968e..7e9fa21eaef 100644 --- a/lib/private/encryption/exceptions/decryptionfailedexception.php +++ b/lib/private/encryption/exceptions/decryptionfailedexception.php @@ -27,4 +27,15 @@ use OCP\Encryption\Exceptions\GenericEncryptionException; class DecryptionFailedException extends GenericEncryptionException { + /** + * @param string $message + * @param int $code + * @param \Exception $previous + * @param string $hint + */ + public function __construct($message = '', $code = 0, \Exception $previous = null, $hint = '') { + parent::__construct($message, $code, $previous, $hint); + +} + } diff --git a/lib/private/encryption/hookmanager.php b/lib/private/encryption/hookmanager.php index c62583b4b47..31ecb2fbcf6 100644 --- a/lib/private/encryption/hookmanager.php +++ b/lib/private/encryption/hookmanager.php @@ -37,6 +37,14 @@ class HookManager { self::getUpdate()->postUnshared($params); } + public static function postRename($params) { + self::getUpdate()->postRename($params); + } + + public static function postRestore($params) { + self::getUpdate()->postRestore($params); + } + /** * @return Update */ diff --git a/lib/private/encryption/keys/storage.php b/lib/private/encryption/keys/storage.php index 118c8dc920d..6aa00c5b5ee 100644 --- a/lib/private/encryption/keys/storage.php +++ b/lib/private/encryption/keys/storage.php @@ -125,10 +125,9 @@ class Storage implements IStorage { /** * @inheritdoc */ - public function deleteAllFileKeys($path, $encryptionModuleId) { - $keyDir = $this->getFileKeyDir($encryptionModuleId, $path); - $path = dirname($keyDir); - return !$this->view->file_exists($path) || $this->view->deleteAll($path); + public function deleteAllFileKeys($path) { + $keyDir = $this->getFileKeyDir('', $path); + return !$this->view->file_exists($keyDir) || $this->view->deleteAll($keyDir); } /** @@ -208,17 +207,10 @@ class Storage implements IStorage { * @param string $encryptionModuleId * @param string $path path to the file, relative to data/ * @return string - * @throws GenericEncryptionException - * @internal param string $keyId */ private function getFileKeyDir($encryptionModuleId, $path) { - if ($this->view->is_dir($path)) { - throw new GenericEncryptionException("file was expected but directory was given: $path"); - } - list($owner, $filename) = $this->util->getUidAndFilename($path); - $filename = $this->util->stripPartialFileExtension($filename); // in case of system wide mount points the keys are stored directly in the data directory if ($this->util->isSystemWideMountPoint($filename, $owner)) { diff --git a/lib/private/encryption/update.php b/lib/private/encryption/update.php index ddcee3bae93..02579fd9136 100644 --- a/lib/private/encryption/update.php +++ b/lib/private/encryption/update.php @@ -108,13 +108,45 @@ class Update { } /** + * inform encryption module that a file was restored from the trash bin, + * e.g. to update the encryption keys + * + * @param array $params + */ + public function postRestore($params) { + if ($this->encryptionManager->isEnabled()) { + $path = Filesystem::normalizePath('/' . $this->uid . '/files/' . $params['filePath']); + $this->update($path); + } + } + + /** + * inform encryption module that a file was renamed, + * e.g. to update the encryption keys + * + * @param array $params + */ + public function postRename($params) { + $source = $params['oldpath']; + $target = $params['newpath']; + if( + $this->encryptionManager->isEnabled() && + dirname($source) !== dirname($target) + ) { + list($owner, $ownerPath) = $this->getOwnerPath($target); + $absPath = '/' . $owner . '/files/' . $ownerPath; + $this->update($absPath); + } + } + + /** * get owner and path relative to data/<owner>/files * * @param string $path path to file for current user * @return array ['owner' => $owner, 'path' => $path] * @throw \InvalidArgumentException */ - private function getOwnerPath($path) { + protected function getOwnerPath($path) { $info = Filesystem::getFileInfo($path); $owner = Filesystem::getOwner($path); $view = new View('/' . $owner . '/files'); diff --git a/lib/private/encryption/util.php b/lib/private/encryption/util.php index 5ea9b8bdeaf..b77672d2f6b 100644 --- a/lib/private/encryption/util.php +++ b/lib/private/encryption/util.php @@ -357,7 +357,7 @@ class Util { public function isExcluded($path) { $normalizedPath = \OC\Files\Filesystem::normalizePath($path); $root = explode('/', $normalizedPath, 4); - if (count($root) > 2) { + if (count($root) > 1) { //detect system wide folders if (in_array($root[1], $this->excludedPaths)) { diff --git a/lib/private/files.php b/lib/private/files.php index 97f9d8163b1..6a739fc844c 100644 --- a/lib/private/files.php +++ b/lib/private/files.php @@ -129,52 +129,60 @@ class OC_Files { $zip = new ZipStreamer(false); } OC_Util::obEnd(); - if ($zip or \OC\Files\Filesystem::isReadable($filename)) { - self::sendHeaders($filename, $name, $zip); - } elseif (!\OC\Files\Filesystem::file_exists($filename)) { - header("HTTP/1.0 404 Not Found"); - $tmpl = new OC_Template('', '404', 'guest'); - $tmpl->printPage(); - } else { - header("HTTP/1.0 403 Forbidden"); - die('403 Forbidden'); - } - if($only_header) { - return ; - } - if ($zip) { - $executionTime = intval(ini_get('max_execution_time')); - set_time_limit(0); - if ($get_type === self::ZIP_FILES) { - foreach ($files as $file) { - $file = $dir . '/' . $file; - if (\OC\Files\Filesystem::is_file($file)) { - $fh = \OC\Files\Filesystem::fopen($file, 'r'); - $zip->addFileFromStream($fh, basename($file)); - fclose($fh); - } elseif (\OC\Files\Filesystem::is_dir($file)) { - self::zipAddDir($file, $zip); + + try { + + if ($zip or \OC\Files\Filesystem::isReadable($filename)) { + self::sendHeaders($filename, $name, $zip); + } elseif (!\OC\Files\Filesystem::file_exists($filename)) { + header("HTTP/1.0 404 Not Found"); + $tmpl = new OC_Template('', '404', 'guest'); + $tmpl->printPage(); + } else { + header("HTTP/1.0 403 Forbidden"); + die('403 Forbidden'); + } + if ($only_header) { + return; + } + if ($zip) { + $executionTime = intval(ini_get('max_execution_time')); + set_time_limit(0); + if ($get_type === self::ZIP_FILES) { + foreach ($files as $file) { + $file = $dir . '/' . $file; + if (\OC\Files\Filesystem::is_file($file)) { + $fh = \OC\Files\Filesystem::fopen($file, 'r'); + $zip->addFileFromStream($fh, basename($file)); + fclose($fh); + } elseif (\OC\Files\Filesystem::is_dir($file)) { + self::zipAddDir($file, $zip); + } } + } elseif ($get_type === self::ZIP_DIR) { + $file = $dir . '/' . $files; + self::zipAddDir($file, $zip); } - } elseif ($get_type === self::ZIP_DIR) { - $file = $dir . '/' . $files; - self::zipAddDir($file, $zip); - } - $zip->finalize(); - set_time_limit($executionTime); - } else { - if ($xsendfile) { - $view = \OC\Files\Filesystem::getView(); - /** @var $storage \OC\Files\Storage\Storage */ - list($storage) = $view->resolvePath($filename); - if ($storage->isLocal()) { - self::addSendfileHeader($filename); + $zip->finalize(); + set_time_limit($executionTime); + } else { + if ($xsendfile) { + $view = \OC\Files\Filesystem::getView(); + /** @var $storage \OC\Files\Storage\Storage */ + list($storage) = $view->resolvePath($filename); + if ($storage->isLocal()) { + self::addSendfileHeader($filename); + } else { + \OC\Files\Filesystem::readfile($filename); + } } else { \OC\Files\Filesystem::readfile($filename); } - } else { - \OC\Files\Filesystem::readfile($filename); } + } catch (\Exception $ex) { + $l = \OC::$server->getL10N('core'); + $hint = method_exists($ex, 'getHint') ? $ex->getHint() : ''; + \OC_Template::printErrorPage($l->t('Can\'t read file'), $hint); } } diff --git a/lib/private/files/storage/dav.php b/lib/private/files/storage/dav.php index 3d9d48c7763..0ddfde15047 100644 --- a/lib/private/files/storage/dav.php +++ b/lib/private/files/storage/dav.php @@ -346,8 +346,12 @@ class DAV extends Common { curl_setopt($curl, CURLOPT_URL, $this->createBaseUri() . $this->encodePath($path)); curl_setopt($curl, CURLOPT_FILE, $fp); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); - curl_setopt($curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); + if(defined('CURLOPT_PROTOCOLS')) { + curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); + } + if(defined('CURLOPT_REDIR_PROTOCOLS')) { + curl_setopt($curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); + } if ($this->secure === true) { curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); diff --git a/lib/private/files/storage/wrapper/encryption.php b/lib/private/files/storage/wrapper/encryption.php index c0c4c6979c2..5d146b2dd1d 100644 --- a/lib/private/files/storage/wrapper/encryption.php +++ b/lib/private/files/storage/wrapper/encryption.php @@ -206,8 +206,7 @@ class Encryption extends Wrapper { $encryptionModule = $this->getEncryptionModule($path); if ($encryptionModule) { - $this->keyStorage->deleteAllFileKeys($this->getFullPath($path), - $encryptionModule->getId()); + $this->keyStorage->deleteAllFileKeys($this->getFullPath($path)); } return $this->storage->unlink($path); @@ -231,13 +230,7 @@ class Encryption extends Wrapper { if (isset($this->unencryptedSize[$source])) { $this->unencryptedSize[$target] = $this->unencryptedSize[$source]; } - $keysRenamed = $this->keyStorage->renameKeys($source, $target); - if ($keysRenamed && - dirname($source) !== dirname($target) && - $this->util->isFile($target) - ) { - $this->update->update($target); - } + $this->keyStorage->renameKeys($source, $target); } } @@ -245,6 +238,49 @@ class Encryption extends Wrapper { } /** + * see http://php.net/manual/en/function.rmdir.php + * + * @param string $path + * @return bool + */ + public function rmdir($path) { + $result = $this->storage->rmdir($path); + $fullPath = $this->getFullPath($path); + if ($result && + $this->util->isExcluded($fullPath) === false && + $this->encryptionManager->isEnabled() + ) { + $this->keyStorage->deleteAllFileKeys($fullPath); + } + + return $result; + } + + /** + * check if a file can be read + * + * @param string $path + * @return bool + */ + public function isReadable($path) { + + $isReadable = true; + + $metaData = $this->getMetaData($path); + if ( + !$this->is_dir($path) && + isset($metaData['encrypted']) && + $metaData['encrypted'] === true + ) { + $fullPath = $this->getFullPath($path); + $module = $this->getEncryptionModule($path); + $isReadable = $module->isReadable($fullPath, $this->uid); + } + + return $this->storage->isReadable($path) && $isReadable; + } + + /** * see http://php.net/manual/en/function.copy.php * * @param string $path1 @@ -275,8 +311,13 @@ class Encryption extends Wrapper { } } $data = $this->getMetaData($path1); - $this->getCache()->put($path2, ['encrypted' => $data['encrypted']]); - $this->updateUnencryptedSize($fullPath2, $data['size']); + + if (isset($data['encrypted'])) { + $this->getCache()->put($path2, ['encrypted' => $data['encrypted']]); + } + if (isset($data['size'])) { + $this->updateUnencryptedSize($fullPath2, $data['size']); + } } return $result; diff --git a/lib/private/files/stream/encryption.php b/lib/private/files/stream/encryption.php index 0262405f367..f2f5b9c9af7 100644 --- a/lib/private/files/stream/encryption.php +++ b/lib/private/files/stream/encryption.php @@ -341,8 +341,8 @@ class Encryption extends Wrapper { } else { $data = ''; } + $this->unencryptedSize = max($this->unencryptedSize, $this->position); } - $this->unencryptedSize = max($this->unencryptedSize, $this->position); return $length; } @@ -356,24 +356,22 @@ class Encryption extends Wrapper { switch ($whence) { case SEEK_SET: - if ($offset < $this->unencryptedSize && $offset >= 0) { - $newPosition = $offset; - } + $newPosition = $offset; break; case SEEK_CUR: - if ($offset >= 0) { - $newPosition = $offset + $this->position; - } + $newPosition = $this->position + $offset; break; case SEEK_END: - if ($this->unencryptedSize + $offset >= 0) { - $newPosition = $this->unencryptedSize + $offset; - } + $newPosition = $this->unencryptedSize + $offset; break; default: return $return; } + if ($newPosition > $this->unencryptedSize || $newPosition < 0) { + return $return; + } + $newFilePosition = floor($newPosition / $this->unencryptedBlockSize) * $this->util->getBlockSize() + $this->headerSize; diff --git a/lib/private/helper.php b/lib/private/helper.php index 144ccbfe228..981447c213b 100644 --- a/lib/private/helper.php +++ b/lib/private/helper.php @@ -394,6 +394,9 @@ class OC_Helper { */ public static function computerFileSize($str) { $str = strtolower($str); + if (is_numeric($str)) { + return $str; + } $bytes_array = array( 'b' => 1, @@ -413,6 +416,8 @@ class OC_Helper { if (preg_match('#([kmgtp]?b?)$#si', $str, $matches) && !empty($bytes_array[$matches[1]])) { $bytes *= $bytes_array[$matches[1]]; + } else { + return false; } $bytes = round($bytes); diff --git a/lib/private/l10n.php b/lib/private/l10n.php index b070a299a16..d367dbae690 100644 --- a/lib/private/l10n.php +++ b/lib/private/l10n.php @@ -385,6 +385,7 @@ class OC_L10N implements \OCP\IL10N { if ($locale === null) { $locale = self::findLanguage(); } + $locale = $this->transformToCLDRLocale($locale); $options = array_merge(array('width' => 'long'), $options); $width = $options['width']; @@ -538,6 +539,7 @@ class OC_L10N implements \OCP\IL10N { */ public function getDateFormat() { $locale = $this->getLanguageCode(); + $locale = $this->transformToCLDRLocale($locale); return Punic\Calendar::getDateFormat('short', $locale); } @@ -546,6 +548,15 @@ class OC_L10N implements \OCP\IL10N { */ public function getFirstWeekDay() { $locale = $this->getLanguageCode(); + $locale = $this->transformToCLDRLocale($locale); return Punic\Calendar::getFirstWeekday($locale); } + + private function transformToCLDRLocale($locale) { + if ($locale === 'sr@latin') { + return 'sr_latn'; + } + + return $locale; + } } diff --git a/lib/private/share/mailnotifications.php b/lib/private/share/mailnotifications.php index 1c15b6e3e1d..7120d8493b0 100644 --- a/lib/private/share/mailnotifications.php +++ b/lib/private/share/mailnotifications.php @@ -122,6 +122,11 @@ class MailNotifications { $args = array( 'dir' => $filename, ); + } else if (strpos($filename, '/')) { + $args = array( + 'dir' => '/' . dirname($filename), + 'scrollto' => basename($filename), + ); } else { $args = array( 'dir' => '/', diff --git a/lib/private/util.php b/lib/private/util.php index 367199f7735..3842d775b24 100644 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -1335,7 +1335,7 @@ class OC_Util { if (ini_get('xcache.admin.enable_auth')) { OC_Log::write('core', 'XCache opcode cache will not be cleared because "xcache.admin.enable_auth" is enabled.', \OC_Log::WARN); } else { - xcache_clear_cache(XC_TYPE_PHP, 0); + @xcache_clear_cache(XC_TYPE_PHP, 0); } } // Opcache (PHP >= 5.5) |