summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/base.php29
-rw-r--r--lib/l10n/ca.php1
-rw-r--r--lib/private/appframework/dependencyinjection/dicontainer.php4
-rw-r--r--lib/private/appframework/http/request.php87
-rw-r--r--lib/private/connector/sabre/file.php6
-rw-r--r--lib/private/davclient.php13
-rw-r--r--lib/private/files/type/detection.php40
-rw-r--r--lib/private/files/view.php11
-rw-r--r--lib/private/group/backend.php2
-rw-r--r--lib/private/group/database.php14
-rw-r--r--lib/private/group/dummy.php10
-rw-r--r--lib/private/group/group.php33
-rw-r--r--lib/private/group/manager.php6
-rw-r--r--lib/private/helper.php10
-rw-r--r--lib/private/json.php2
-rw-r--r--lib/private/l10n.php8
-rw-r--r--lib/private/mimetypes.list.php214
-rwxr-xr-xlib/private/preview.php234
-rw-r--r--lib/private/preview/movies.php37
-rw-r--r--lib/private/server.php9
-rw-r--r--lib/private/share/share.php10
-rw-r--r--lib/private/template.php23
-rw-r--r--lib/private/template/functions.php9
-rw-r--r--lib/private/templatelayout.php31
-rw-r--r--lib/private/user/manager.php14
-rwxr-xr-xlib/private/util.php2
-rw-r--r--lib/public/appframework/http/jsonresponse.php1
27 files changed, 524 insertions, 336 deletions
diff --git a/lib/base.php b/lib/base.php
index 6ea77aa7a58..7098f480e27 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -213,6 +213,34 @@ class OC {
}
}
+ /*
+ * This function adds some security related headers to all requests served via base.php
+ * The implementation of this function has to happen here to ensure that all third-party
+ * components (e.g. SabreDAV) also benefit from this headers.
+ */
+ public static function addSecurityHeaders() {
+ header('X-XSS-Protection: 1; mode=block'); // Enforce browser based XSS filters
+ header('X-Content-Type-Options: nosniff'); // Disable sniffing the content type for IE
+
+ // iFrame Restriction Policy
+ $xFramePolicy = OC_Config::getValue('xframe_restriction', true);
+ if($xFramePolicy) {
+ header('X-Frame-Options: Sameorigin'); // Disallow iFraming from other domains
+ }
+
+ // Content Security Policy
+ // If you change the standard policy, please also change it in config.sample.php
+ $policy = OC_Config::getValue('custom_csp_policy',
+ 'default-src \'self\'; '
+ .'script-src \'self\' \'unsafe-eval\'; '
+ .'style-src \'self\' \'unsafe-inline\'; '
+ .'frame-src *; '
+ .'img-src *; '
+ .'font-src \'self\' data:; '
+ .'media-src *');
+ header('Content-Security-Policy:'.$policy);
+ }
+
public static function checkSSL() {
// redirect to https site if configured
if (OC_Config::getValue("forcessl", false)) {
@@ -512,6 +540,7 @@ class OC {
self::checkConfig();
self::checkInstalled();
self::checkSSL();
+ self::addSecurityHeaders();
$errors = OC_Util::checkServer();
if (count($errors) > 0) {
diff --git a/lib/l10n/ca.php b/lib/l10n/ca.php
index 477cdf2925b..22d8c457f5e 100644
--- a/lib/l10n/ca.php
+++ b/lib/l10n/ca.php
@@ -67,6 +67,7 @@ $TRANSLATIONS = array(
"_%n month ago_::_%n months ago_" => array("fa %n mes","fa %n mesos"),
"last year" => "l'any passat",
"years ago" => "anys enrere",
+"Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-\"" => "Només els caràcters següents estan permesos en el nom d'usuari: \"a-z\", \"A-Z\", \"0-9\" i \"_.@-\"",
"A valid username must be provided" => "Heu de facilitar un nom d'usuari vàlid",
"A valid password must be provided" => "Heu de facilitar una contrasenya vàlida",
"The username is already being used" => "El nom d'usuari ja està en ús"
diff --git a/lib/private/appframework/dependencyinjection/dicontainer.php b/lib/private/appframework/dependencyinjection/dicontainer.php
index 78224ea54c0..e478225a53d 100644
--- a/lib/private/appframework/dependencyinjection/dicontainer.php
+++ b/lib/private/appframework/dependencyinjection/dicontainer.php
@@ -92,8 +92,8 @@ class DIContainer extends SimpleContainer implements IAppContainer{
return new SecurityMiddleware($app, $c['Request']);
});
- $middleWares = $this->middleWares;
- $this['MiddlewareDispatcher'] = $this->share(function($c) use ($middleWares) {
+ $middleWares = &$this->middleWares;
+ $this['MiddlewareDispatcher'] = $this->share(function($c) use (&$middleWares) {
$dispatcher = new MiddlewareDispatcher();
$dispatcher->registerMiddleware($c['SecurityMiddleware']);
diff --git a/lib/private/appframework/http/request.php b/lib/private/appframework/http/request.php
index 40f47a7bd2f..643fa685adc 100644
--- a/lib/private/appframework/http/request.php
+++ b/lib/private/appframework/http/request.php
@@ -60,7 +60,14 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* @param string|false 'requesttoken' the requesttoken or false when not available
* @see http://www.php.net/manual/en/reserved.variables.php
*/
- public function __construct(array $vars=array()) {
+ public function __construct(array $vars=array(), $stream='php://input') {
+
+ $this->inputStream = $stream;
+ $this->items['params'] = array();
+
+ if(!array_key_exists('method', $vars)) {
+ $vars['method'] = 'GET';
+ }
foreach($this->allowedKeys as $name) {
$this->items[$name] = isset($vars[$name])
@@ -68,25 +75,32 @@ class Request implements \ArrayAccess, \Countable, IRequest {
: array();
}
- if (defined('PHPUNIT_RUN') && PHPUNIT_RUN
- && in_array('fakeinput', stream_get_wrappers())) {
- $this->inputStream = 'fakeinput://data';
- } else {
- $this->inputStream = 'php://input';
- }
-
- // Only 'application/x-www-form-urlencoded' requests are automatically
- // transformed by PHP, 'application/json' must be decoded manually.
- if ($this->method === 'POST'
- && strpos($this->getHeader('Content-Type'), 'application/json') !== false
- ) {
- $this->items['params'] = $this->items['post'] = json_decode(file_get_contents($this->inputStream), true);
- }
+ // 'application/json' must be decoded manually.
+ if (strpos($this->getHeader('Content-Type'), 'application/json') !== false) {
+ $params = json_decode(file_get_contents($this->inputStream), true);
+ if(count($params) > 0) {
+ $this->items['params'] = $params;
+ if($vars['method'] === 'POST') {
+ $this->items['post'] = $params;
+ }
+ }
+ // Handle application/x-www-form-urlencoded for methods other than GET
+ // or post correctly
+ } elseif($vars['method'] !== 'GET'
+ && $vars['method'] !== 'POST'
+ && strpos($this->getHeader('Content-Type'), 'application/x-www-form-urlencoded') !== false) {
+
+ parse_str(file_get_contents($this->inputStream), $params);
+ if(is_array($params)) {
+ $this->items['params'] = $params;
+ }
+ }
$this->items['parameters'] = array_merge(
$this->items['get'],
$this->items['post'],
- $this->items['urlParams']
+ $this->items['urlParams'],
+ $this->items['params']
);
}
@@ -313,47 +327,22 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* @throws \LogicException
*/
protected function getContent() {
- if ($this->content === false && $this->method === 'PUT') {
- throw new \LogicException(
- '"put" can only be accessed once if not '
- . 'application/x-www-form-urlencoded or application/json.'
- );
- }
-
// If the content can't be parsed into an array then return a stream resource.
if ($this->method === 'PUT'
&& strpos($this->getHeader('Content-Type'), 'application/x-www-form-urlencoded') === false
&& strpos($this->getHeader('Content-Type'), 'application/json') === false
) {
+ if ($this->content === false) {
+ throw new \LogicException(
+ '"put" can only be accessed once if not '
+ . 'application/x-www-form-urlencoded or application/json.'
+ );
+ }
$this->content = false;
return fopen($this->inputStream, 'rb');
+ } else {
+ return $this->parameters;
}
-
- if (is_null($this->content)) {
- $this->content = file_get_contents($this->inputStream);
-
- /*
- * Normal jquery ajax requests are sent as application/x-www-form-urlencoded
- * and in $_GET and $_POST PHP transformes the data into an array.
- * The first condition mimics this.
- * The second condition allows for sending raw application/json data while
- * still getting the result as an array.
- *
- */
- if (strpos($this->getHeader('Content-Type'), 'application/x-www-form-urlencoded') !== false) {
- parse_str($this->content, $content);
- if(is_array($content)) {
- $this->content = $content;
- }
- } elseif (strpos($this->getHeader('Content-Type'), 'application/json') !== false) {
- $content = json_decode($this->content, true);
- if(is_array($content)) {
- $this->content = $content;
- }
- }
- }
-
- return $this->content;
}
/**
diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php
index ef6caaf22a7..750d646a8f5 100644
--- a/lib/private/connector/sabre/file.php
+++ b/lib/private/connector/sabre/file.php
@@ -205,10 +205,12 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
*/
public function getContentType() {
if (isset($this->fileinfo_cache['mimetype'])) {
- return $this->fileinfo_cache['mimetype'];
+ $mimeType = $this->fileinfo_cache['mimetype'];
+ } else {
+ $mimeType = \OC\Files\Filesystem::getMimeType($this->path);
}
- return \OC\Files\Filesystem::getMimeType($this->path);
+ return \OC_Helper::getSecureMimeType($mimeType);
}
diff --git a/lib/private/davclient.php b/lib/private/davclient.php
index afa4e1103b4..916dc11d17a 100644
--- a/lib/private/davclient.php
+++ b/lib/private/davclient.php
@@ -29,6 +29,8 @@ class OC_DAVClient extends \Sabre_DAV_Client {
protected $requestTimeout;
+ protected $verifyHost;
+
/**
* @brief Sets the request timeout or 0 to disable timeout.
* @param integer $timeout in seconds or 0 to disable
@@ -37,10 +39,21 @@ class OC_DAVClient extends \Sabre_DAV_Client {
$this->requestTimeout = (int)$timeout;
}
+ /**
+ * @brief Sets the CURLOPT_SSL_VERIFYHOST setting
+ * @param integer $value value to set CURLOPT_SSL_VERIFYHOST to
+ */
+ public function setVerifyHost($value) {
+ $this->verifyHost = $value;
+ }
+
protected function curlRequest($url, $settings) {
if ($this->requestTimeout > 0) {
$settings[CURLOPT_TIMEOUT] = $this->requestTimeout;
}
+ if (!is_null($this->verifyHost)) {
+ $settings[CURLOPT_SSL_VERIFYHOST] = $this->verifyHost;
+ }
return parent::curlRequest($url, $settings);
}
}
diff --git a/lib/private/files/type/detection.php b/lib/private/files/type/detection.php
index 11e439032ce..8ee53917814 100644
--- a/lib/private/files/type/detection.php
+++ b/lib/private/files/type/detection.php
@@ -17,24 +17,40 @@ namespace OC\Files\Type;
*/
class Detection {
protected $mimetypes = array();
+ protected $secureMimeTypes = array();
/**
- * add an extension -> mimetype mapping
+ * Add an extension -> mimetype mapping
+ *
+ * $mimetype is the assumed correct mime type
+ * The optional $secureMimeType is an alternative to send to send
+ * to avoid potential XSS.
*
* @param string $extension
* @param string $mimetype
+ * @param string|null $secureMimeType
*/
- public function registerType($extension, $mimetype) {
- $this->mimetypes[$extension] = $mimetype;
+ public function registerType($extension, $mimetype, $secureMimeType = null) {
+ $this->mimetypes[$extension] = array($mimetype, $secureMimeType);
+ $this->secureMimeTypes[$mimetype] = $secureMimeType ?: $mimetype;
}
/**
- * add an array of extension -> mimetype mappings
+ * Add an array of extension -> mimetype mappings
+ *
+ * The mimetype value is in itself an array where the first index is
+ * the assumed correct mimetype and the second is either a secure alternative
+ * or null if the correct is considered secure.
*
* @param array $types
*/
public function registerTypeArray($types) {
$this->mimetypes = array_merge($this->mimetypes, $types);
+
+ // Update the alternative mimetypes to avoid having to look them up each time.
+ foreach ($this->mimetypes as $mimeType) {
+ $this->secureMimeTypes[$mimeType[0]] = $mimeType[1] ?: $mimeType[0];
+ }
}
/**
@@ -48,7 +64,9 @@ class Detection {
//try to guess the type by the file extension
$extension = strtolower(strrchr(basename($path), "."));
$extension = substr($extension, 1); //remove leading .
- return (isset($this->mimetypes[$extension])) ? $this->mimetypes[$extension] : 'application/octet-stream';
+ return (isset($this->mimetypes[$extension]) && isset($this->mimetypes[$extension][0]))
+ ? $this->mimetypes[$extension][0]
+ : 'application/octet-stream';
} else {
return 'application/octet-stream';
}
@@ -123,4 +141,16 @@ class Detection {
return $mime;
}
}
+
+ /**
+ * Get a secure mimetype that won't expose potential XSS.
+ *
+ * @param string $mimeType
+ * @return string
+ */
+ public function getSecureMimeType($mimeType) {
+ return isset($this->secureMimeTypes[$mimeType])
+ ? $this->secureMimeTypes[$mimeType]
+ : 'application/octet-stream';
+ }
}
diff --git a/lib/private/files/view.php b/lib/private/files/view.php
index 94be7114865..519ed250b1f 100644
--- a/lib/private/files/view.php
+++ b/lib/private/files/view.php
@@ -629,10 +629,21 @@ class View {
}
public function fromTmpFile($tmpFile, $path) {
+
if (Filesystem::isValidPath($path)) {
+
+ // Get directory that the file is going into
+ $filePath = dirname($path);
+
+ // Create the directories if any
+ if (!$this->file_exists($filePath)) {
+ $this->mkdir($filePath);
+ }
+
if (!$tmpFile) {
debug_print_backtrace();
}
+
$source = fopen($tmpFile, 'r');
if ($source) {
$this->file_put_contents($path, $source);
diff --git a/lib/private/group/backend.php b/lib/private/group/backend.php
index 2e17b5d0b7f..b0ed0d90d76 100644
--- a/lib/private/group/backend.php
+++ b/lib/private/group/backend.php
@@ -34,6 +34,7 @@ define('OC_GROUP_BACKEND_DELETE_GROUP', 0x00000010);
define('OC_GROUP_BACKEND_ADD_TO_GROUP', 0x00000100);
define('OC_GROUP_BACKEND_REMOVE_FROM_GOUP', 0x00001000);
define('OC_GROUP_BACKEND_GET_DISPLAYNAME', 0x00010000);
+define('OC_GROUP_BACKEND_COUNT_USERS', 0x00100000);
/**
* Abstract base class for user management
@@ -45,6 +46,7 @@ abstract class OC_Group_Backend implements OC_Group_Interface {
OC_GROUP_BACKEND_ADD_TO_GROUP => 'addToGroup',
OC_GROUP_BACKEND_REMOVE_FROM_GOUP => 'removeFromGroup',
OC_GROUP_BACKEND_GET_DISPLAYNAME => 'displayNamesInGroup',
+ OC_GROUP_BACKEND_COUNT_USERS => 'countUsersInGroup',
);
/**
diff --git a/lib/private/group/database.php b/lib/private/group/database.php
index d0974685ff6..3815dcff2e5 100644
--- a/lib/private/group/database.php
+++ b/lib/private/group/database.php
@@ -212,6 +212,20 @@ class OC_Group_Database extends OC_Group_Backend {
}
/**
+ * @brief get the number of all users matching the search string in a group
+ * @param string $gid
+ * @param string $search
+ * @param int $limit
+ * @param int $offset
+ * @return int | false
+ */
+ public function countUsersInGroup($gid, $search = '') {
+ $stmt = OC_DB::prepare('SELECT COUNT(`uid`) AS `count` FROM `*PREFIX*group_user` WHERE `gid` = ? AND `uid` LIKE ?');
+ $result = $stmt->execute(array($gid, $search.'%'));
+ return $result->fetchOne();
+ }
+
+ /**
* @brief get a list of all display names in a group
* @param string $gid
* @param string $search
diff --git a/lib/private/group/dummy.php b/lib/private/group/dummy.php
index da26e1b910e..94cbb607ad1 100644
--- a/lib/private/group/dummy.php
+++ b/lib/private/group/dummy.php
@@ -157,4 +157,14 @@ class OC_Group_Dummy extends OC_Group_Backend {
}
}
+ /**
+ * @brief get the number of all users in a group
+ * @returns int | bool
+ */
+ public function countUsersInGroup($gid, $search = '', $limit = -1, $offset = 0) {
+ if(isset($this->groups[$gid])) {
+ return count($this->groups[$gid]);
+ }
+ }
+
}
diff --git a/lib/private/group/group.php b/lib/private/group/group.php
index 8d2aa87a788..3efbb6e7023 100644
--- a/lib/private/group/group.php
+++ b/lib/private/group/group.php
@@ -172,12 +172,6 @@ class Group {
$users = array();
foreach ($this->backends as $backend) {
$userIds = $backend->usersInGroup($this->gid, $search, $limit, $offset);
- if (!is_null($limit)) {
- $limit -= count($userIds);
- }
- if (!is_null($offset)) {
- $offset -= count($userIds);
- }
$users += $this->getVerifiedUsers($userIds);
if (!is_null($limit) and $limit <= 0) {
return array_values($users);
@@ -187,6 +181,27 @@ class Group {
}
/**
+ * returns the number of users matching the search string
+ *
+ * @param string $search
+ * @return int | bool
+ */
+ public function count($search) {
+ $users = false;
+ foreach ($this->backends as $backend) {
+ if($backend->implementsActions(OC_GROUP_BACKEND_COUNT_USERS)) {
+ if($users === false) {
+ //we could directly add to a bool variable, but this would
+ //be ugly
+ $users = 0;
+ }
+ $users += $backend->countUsersInGroup($this->gid, $search);
+ }
+ }
+ return $users;
+ }
+
+ /**
* search for users in the group by displayname
*
* @param string $search
@@ -202,12 +217,6 @@ class Group {
} else {
$userIds = $backend->usersInGroup($this->gid, $search, $limit, $offset);
}
- if (!is_null($limit)) {
- $limit -= count($userIds);
- }
- if (!is_null($offset)) {
- $offset -= count($userIds);
- }
$users = $this->getVerifiedUsers($userIds);
if (!is_null($limit) and $limit <= 0) {
return array_values($users);
diff --git a/lib/private/group/manager.php b/lib/private/group/manager.php
index 9b433b64fd4..f591bd32aba 100644
--- a/lib/private/group/manager.php
+++ b/lib/private/group/manager.php
@@ -134,12 +134,6 @@ class Manager extends PublicEmitter {
$groups = array();
foreach ($this->backends as $backend) {
$groupIds = $backend->getGroups($search, $limit, $offset);
- if (!is_null($limit)) {
- $limit -= count($groupIds);
- }
- if (!is_null($offset)) {
- $offset -= count($groupIds);
- }
foreach ($groupIds as $groupId) {
$groups[$groupId] = $this->getGroupObject($groupId);
}
diff --git a/lib/private/helper.php b/lib/private/helper.php
index da3d3cd1c6e..d5214823de9 100644
--- a/lib/private/helper.php
+++ b/lib/private/helper.php
@@ -431,6 +431,16 @@ class OC_Helper {
}
/**
+ * Get a secure mimetype that won't expose potential XSS.
+ *
+ * @param string $mimeType
+ * @return string
+ */
+ static function getSecureMimeType($mimeType) {
+ return self::getMimetypeDetector()->getSecureMimeType($mimeType);
+ }
+
+ /**
* get the mimetype form a data string
*
* @param string $data
diff --git a/lib/private/json.php b/lib/private/json.php
index 4ccdb490a6c..34f81c3b8cf 100644
--- a/lib/private/json.php
+++ b/lib/private/json.php
@@ -119,8 +119,6 @@ class OC_JSON{
* Encode and print $data in json format
*/
public static function encodedPrint($data, $setContentType=true) {
- // Disable mimesniffing, don't move this to setContentTypeHeader!
- header( 'X-Content-Type-Options: nosniff' );
if($setContentType) {
self::setContentTypeHeader();
}
diff --git a/lib/private/l10n.php b/lib/private/l10n.php
index 175360e27a3..a397945b829 100644
--- a/lib/private/l10n.php
+++ b/lib/private/l10n.php
@@ -419,6 +419,14 @@ class OC_L10N implements \OCP\IL10N {
}
/**
+ * The given language is forced to be used while executing the current request
+ * @param string $lang
+ */
+ public static function forceLanguage($lang) {
+ self::$language = $lang;
+ }
+
+ /**
* @brief find the best language
* @param array|string $app details below
* @returns string language
diff --git a/lib/private/mimetypes.list.php b/lib/private/mimetypes.list.php
index 91bcf584267..07e2391c116 100644
--- a/lib/private/mimetypes.list.php
+++ b/lib/private/mimetypes.list.php
@@ -22,111 +22,115 @@
/**
* Array mapping file extensions to mimetypes (in alphabetical order).
+ *
+ * The first index in the mime type array is the assumed correct mimetype
+ * and the second is either a secure alternative or null if the correct
+ * is considered secure.
*/
return array(
- '7z' => 'application/x-7z-compressed',
- 'accdb' => 'application/msaccess',
- 'ai' => 'application/illustrator',
- 'avi' => 'video/x-msvideo',
- 'bash' => 'text/x-shellscript',
- 'blend' => 'application/x-blender',
- 'bin' => 'application/x-bin',
- 'bmp' => 'image/bmp',
- 'cb7' => 'application/x-cbr',
- 'cba' => 'application/x-cbr',
- 'cbr' => 'application/x-cbr',
- 'cbt' => 'application/x-cbr',
- 'cbtc' => 'application/x-cbr',
- 'cbz' => 'application/x-cbr',
- 'cc' => 'text/x-c',
- 'cdr' => 'application/coreldraw',
- 'cpp' => 'text/x-c++src',
- 'css' => 'text/css',
- 'csv' => 'text/csv',
- 'cvbdl' => 'application/x-cbr',
- 'c' => 'text/x-c',
- 'c++' => 'text/x-c++src',
- 'deb' => 'application/x-deb',
- 'doc' => 'application/msword',
- 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
- 'dot' => 'application/msword',
- 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
- 'dv' => 'video/dv',
- 'eot' => 'application/vnd.ms-fontobject',
- 'epub' => 'application/epub+zip',
- 'exe' => 'application/x-ms-dos-executable',
- 'flac' => 'audio/flac',
- 'gif' => 'image/gif',
- 'gz' => 'application/x-gzip',
- 'gzip' => 'application/x-gzip',
- 'html' => 'text/html',
- 'htm' => 'text/html',
- 'ical' => 'text/calendar',
- 'ics' => 'text/calendar',
- 'impress' => 'text/impress',
- 'jpeg' => 'image/jpeg',
- 'jpg' => 'image/jpeg',
- 'js' => 'application/javascript',
- 'json' => 'application/json',
- 'keynote' => 'application/x-iwork-keynote-sffkey',
- 'kra' => 'application/x-krita',
- 'm2t' => 'video/mp2t',
- 'm4v' => 'video/mp4',
- 'markdown' => 'text/markdown',
- 'mdown' => 'text/markdown',
- 'md' => 'text/markdown',
- 'mdb' => 'application/msaccess',
- 'mdwn' => 'text/markdown',
- 'mkv' => 'video/x-matroska',
- 'mobi' => 'application/x-mobipocket-ebook',
- 'mov' => 'video/quicktime',
- 'mp3' => 'audio/mpeg',
- 'mp4' => 'video/mp4',
- 'mpeg' => 'video/mpeg',
- 'mpg' => 'video/mpeg',
- 'msi' => 'application/x-msi',
- 'numbers' => 'application/x-iwork-numbers-sffnumbers',
- 'odg' => 'application/vnd.oasis.opendocument.graphics',
- 'odp' => 'application/vnd.oasis.opendocument.presentation',
- 'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
- 'odt' => 'application/vnd.oasis.opendocument.text',
- 'oga' => 'audio/ogg',
- 'ogg' => 'audio/ogg',
- 'ogv' => 'video/ogg',
- 'otf' => 'font/opentype',
- 'pages' => 'application/x-iwork-pages-sffpages',
- 'pdf' => 'application/pdf',
- 'php' => 'application/x-php',
- 'pl' => 'application/x-perl',
- 'png' => 'image/png',
- 'ppt' => 'application/mspowerpoint',
- 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
- 'psd' => 'application/x-photoshop',
- 'py' => 'text/x-python',
- 'rar' => 'application/x-rar-compressed',
- 'reveal' => 'text/reveal',
- 'sgf' => 'application/sgf',
- 'sh-lib' => 'text/x-shellscript',
- 'sh' => 'text/x-shellscript',
- 'svg' => 'image/svg+xml',
- 'swf' => 'application/x-shockwave-flash',
- 'tar' => 'application/x-tar',
- 'tar.gz' => 'application/x-compressed',
- 'tex' => 'application/x-tex',
- 'tgz' => 'application/x-compressed',
- 'tiff' => 'image/tiff',
- 'tif' => 'image/tiff',
- 'ttf' => 'application/x-font-ttf',
- 'txt' => 'text/plain',
- 'vcard' => 'text/vcard',
- 'vcf' => 'text/vcard',
- 'wav' => 'audio/wav',
- 'webm' => 'video/webm',
- 'woff' => 'application/font-woff',
- 'wmv' => 'video/x-ms-asf',
- 'xcf' => 'application/x-gimp',
- 'xls' => 'application/msexcel',
- 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
- 'xml' => 'application/xml',
- 'zip' => 'application/zip',
+ '7z' => array('application/x-7z-compressed', null),
+ 'accdb' => array('application/msaccess', null),
+ 'ai' => array('application/illustrator', null),
+ 'avi' => array('video/x-msvideo', null),
+ 'bash' => array('text/x-shellscript', null),
+ 'blend' => array('application/x-blender', null),
+ 'bin' => array('application/x-bin', null),
+ 'bmp' => array('image/bmp', null),
+ 'cb7' => array('application/x-cbr', null),
+ 'cba' => array('application/x-cbr', null),
+ 'cbr' => array('application/x-cbr', null),
+ 'cbt' => array('application/x-cbr', null),
+ 'cbtc' => array('application/x-cbr', null),
+ 'cbz' => array('application/x-cbr', null),
+ 'cc' => array('text/x-c', null),
+ 'cdr' => array('application/coreldraw', null),
+ 'cpp' => array('text/x-c++src', null),
+ 'css' => array('text/css', null),
+ 'csv' => array('text/csv', null),
+ 'cvbdl' => array('application/x-cbr', null),
+ 'c' => array('text/x-c', null),
+ 'c++' => array('text/x-c++src', null),
+ 'deb' => array('application/x-deb', null),
+ 'doc' => array('application/msword', null),
+ 'docx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', null),
+ 'dot' => array('application/msword', null),
+ 'dotx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.template', null),
+ 'dv' => array('video/dv', null),
+ 'eot' => array('application/vnd.ms-fontobject', null),
+ 'epub' => array('application/epub+zip', null),
+ 'exe' => array('application/x-ms-dos-executable', null),
+ 'flac' => array('audio/flac', null),
+ 'gif' => array('image/gif', null),
+ 'gz' => array('application/x-gzip', null),
+ 'gzip' => array('application/x-gzip', null),
+ 'html' => array('text/html', 'text/plain'),
+ 'htm' => array('text/html', 'text/plain'),
+ 'ical' => array('text/calendar', null),
+ 'ics' => array('text/calendar', null),
+ 'impress' => array('text/impress', null),
+ 'jpeg' => array('image/jpeg', null),
+ 'jpg' => array('image/jpeg', null),
+ 'js' => array('application/javascript', 'text/plain'),
+ 'json' => array('application/json', 'text/plain'),
+ 'keynote' => array('application/x-iwork-keynote-sffkey', null),
+ 'kra' => array('application/x-krita', null),
+ 'm2t' => array('video/mp2t', null),
+ 'm4v' => array('video/mp4', null),
+ 'markdown' => array('text/markdown', null),
+ 'mdown' => array('text/markdown', null),
+ 'md' => array('text/markdown', null),
+ 'mdb' => array('application/msaccess', null),
+ 'mdwn' => array('text/markdown', null),
+ 'mkv' => array('video/x-matroska', null),
+ 'mobi' => array('application/x-mobipocket-ebook', null),
+ 'mov' => array('video/quicktime', null),
+ 'mp3' => array('audio/mpeg', null),
+ 'mp4' => array('video/mp4', null),
+ 'mpeg' => array('video/mpeg', null),
+ 'mpg' => array('video/mpeg', null),
+ 'msi' => array('application/x-msi', null),
+ 'numbers' => array('application/x-iwork-numbers-sffnumbers', null),
+ 'odg' => array('application/vnd.oasis.opendocument.graphics', null),
+ 'odp' => array('application/vnd.oasis.opendocument.presentation', null),
+ 'ods' => array('application/vnd.oasis.opendocument.spreadsheet', null),
+ 'odt' => array('application/vnd.oasis.opendocument.text', null),
+ 'oga' => array('audio/ogg', null),
+ 'ogg' => array('audio/ogg', null),
+ 'ogv' => array('video/ogg', null),
+ 'otf' => array('font/opentype', null),
+ 'pages' => array('application/x-iwork-pages-sffpages', null),
+ 'pdf' => array('application/pdf', null),
+ 'php' => array('application/x-php', null),
+ 'pl' => array('application/x-perl', null),
+ 'png' => array('image/png', null),
+ 'ppt' => array('application/mspowerpoint', null),
+ 'pptx' => array('application/vnd.openxmlformats-officedocument.presentationml.presentation', null),
+ 'psd' => array('application/x-photoshop', null),
+ 'py' => array('text/x-python', null),
+ 'rar' => array('application/x-rar-compressed', null),
+ 'reveal' => array('text/reveal', null),
+ 'sgf' => array('application/sgf', null),
+ 'sh-lib' => array('text/x-shellscript', null),
+ 'sh' => array('text/x-shellscript', null),
+ 'svg' => array('image/svg+xml', 'text/plain'),
+ 'swf' => array('application/x-shockwave-flash', 'application/octet-stream'),
+ 'tar' => array('application/x-tar', null),
+ 'tar.gz' => array('application/x-compressed', null),
+ 'tex' => array('application/x-tex', null),
+ 'tgz' => array('application/x-compressed', null),
+ 'tiff' => array('image/tiff', null),
+ 'tif' => array('image/tiff', null),
+ 'ttf' => array('application/x-font-ttf', null),
+ 'txt' => array('text/plain', null),
+ 'vcard' => array('text/vcard', null),
+ 'vcf' => array('text/vcard', null),
+ 'wav' => array('audio/wav', null),
+ 'webm' => array('video/webm', null),
+ 'woff' => array('application/font-woff', null),
+ 'wmv' => array('video/x-ms-asf', null),
+ 'xcf' => array('application/x-gimp', null),
+ 'xls' => array('application/msexcel', null),
+ 'xlsx' => array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', null),
+ 'xml' => array('application/xml', 'text/plain'),
+ 'zip' => array('application/zip', null),
);
diff --git a/lib/private/preview.php b/lib/private/preview.php
index 26016555a32..0187b4aacbb 100755
--- a/lib/private/preview.php
+++ b/lib/private/preview.php
@@ -13,6 +13,8 @@
*/
namespace OC;
+use OC\Preview\Provider;
+
require_once 'preview/image.php';
require_once 'preview/movies.php';
require_once 'preview/mp3.php';
@@ -39,15 +41,16 @@ class Preview {
private $file;
private $maxX;
private $maxY;
- private $scalingup;
- private $mimetype;
+ private $scalingUp;
+ private $mimeType;
//filemapper used for deleting previews
// index is path, value is fileinfo
static public $deleteFileMapper = array();
- //preview images object
/**
+ * preview images object
+ *
* @var \OC_Image
*/
private $preview;
@@ -109,7 +112,7 @@ class Preview {
* @brief returns the path of the file you want a thumbnail from
* @return string
*/
- public function getFile() {
+ public function getFile() {
return $this->file;
}
@@ -134,7 +137,7 @@ class Preview {
* @return bool
*/
public function getScalingUp() {
- return $this->scalingup;
+ return $this->scalingUp;
}
/**
@@ -191,18 +194,18 @@ class Preview {
if ($file !== '') {
$this->getFileInfo();
if($this->info !== null && $this->info !== false) {
- $this->mimetype = $this->info->getMimetype();
+ $this->mimeType = $this->info->getMimetype();
}
}
return $this;
}
/**
- * @brief set mimetype explicitely
- * @param string $mimetype
+ * @brief set mime type explicitly
+ * @param string $mimeType
*/
- public function setMimetype($mimetype) {
- $this->mimetype = $mimetype;
+ public function setMimetype($mimeType) {
+ $this->mimeType = $mimeType;
}
/**
@@ -254,7 +257,7 @@ class Preview {
if ($this->getMaxScaleFactor() === 1) {
$scalingUp = false;
}
- $this->scalingup = $scalingUp;
+ $this->scalingUp = $scalingUp;
return $this;
}
@@ -314,35 +317,68 @@ class Preview {
/**
* @brief check if thumbnail or bigger version of thumbnail of file is cached
- * @return mixed (bool / string)
- * false if thumbnail does not exist
- * path to thumbnail if thumbnail exists
+ * @param int $fileId fileId of the original image
+ * @return string|false path to thumbnail if it exists or false
*/
- private function isCached() {
- $file = $this->getFile();
+ public function isCached($fileId) {
+ if (is_null($fileId)) {
+ return false;
+ }
+
$maxX = $this->getMaxX();
$maxY = $this->getMaxY();
- $scalingUp = $this->getScalingUp();
- $maxScaleFactor = $this->getMaxScaleFactor();
- $fileInfo = $this->getFileInfo($file);
- $fileId = $fileInfo->getId();
+ $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/';
+
+ //does a preview with the wanted height and width already exist?
+ if ($this->userView->file_exists($previewPath . $maxX . '-' . $maxY . '.png')) {
+ return $previewPath . $maxX . '-' . $maxY . '.png';
+ }
+
+ return $this->isCachedBigger($fileId);
+ }
+
+ /**
+ * @brief check if a bigger version of thumbnail of file is cached
+ * @param int $fileId fileId of the original image
+ * @return string|false path to bigger thumbnail if it exists or false
+ */
+ private function isCachedBigger($fileId) {
if (is_null($fileId)) {
return false;
}
- $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/';
- if (!$this->userView->is_dir($previewPath)) {
- return false;
+ $maxX = $this->getMaxX();
+
+ //array for usable cached thumbnails
+ $possibleThumbnails = $this->getPossibleThumbnails($fileId);
+
+ foreach ($possibleThumbnails as $width => $path) {
+ if ($width < $maxX) {
+ continue;
+ } else {
+ return $path;
+ }
}
- //does a preview with the wanted height and width already exist?
- if ($this->userView->file_exists($previewPath . $maxX . '-' . $maxY . '.png')) {
- return $previewPath . $maxX . '-' . $maxY . '.png';
+ return false;
+ }
+
+ /**
+ * @brief get possible bigger thumbnails of the given image
+ * @param int $fileId fileId of the original image
+ * @return array of paths to bigger thumbnails
+ */
+ private function getPossibleThumbnails($fileId) {
+
+ if (is_null($fileId)) {
+ return array();
}
- $wantedAspectRatio = (float)($maxX / $maxY);
+ $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/';
+
+ $wantedAspectRatio = (float) ($this->getMaxX() / $this->getMaxY());
//array for usable cached thumbnails
$possibleThumbnails = array();
@@ -350,53 +386,47 @@ class Preview {
$allThumbnails = $this->userView->getDirectoryContent($previewPath);
foreach ($allThumbnails as $thumbnail) {
$name = rtrim($thumbnail['name'], '.png');
- $size = explode('-', $name);
- $x = (int)$size[0];
- $y = (int)$size[1];
+ list($x, $y, $aspectRatio) = $this->getDimensionsFromFilename($name);
- $aspectRatio = (float)($x / $y);
- if ($aspectRatio !== $wantedAspectRatio) {
+ if (abs($aspectRatio - $wantedAspectRatio) >= 0.000001
+ || $this->unscalable($x, $y)
+ ) {
continue;
}
-
- if ($x < $maxX || $y < $maxY) {
- if ($scalingUp) {
- $scalefactor = $maxX / $x;
- if ($scalefactor > $maxScaleFactor) {
- continue;
- }
- } else {
- continue;
- }
- }
$possibleThumbnails[$x] = $thumbnail['path'];
}
- if (count($possibleThumbnails) === 0) {
- return false;
- }
-
- if (count($possibleThumbnails) === 1) {
- return current($possibleThumbnails);
- }
-
ksort($possibleThumbnails);
- if (key(reset($possibleThumbnails)) > $maxX) {
- return current(reset($possibleThumbnails));
- }
+ return $possibleThumbnails;
+ }
- if (key(end($possibleThumbnails)) < $maxX) {
- return current(end($possibleThumbnails));
- }
+ private function getDimensionsFromFilename($name) {
+ $size = explode('-', $name);
+ $x = (int) $size[0];
+ $y = (int) $size[1];
+ $aspectRatio = (float) ($x / $y);
+ return array($x, $y, $aspectRatio);
+ }
- foreach ($possibleThumbnails as $width => $path) {
- if ($width < $maxX) {
- continue;
+ private function unscalable($x, $y) {
+
+ $maxX = $this->getMaxX();
+ $maxY = $this->getMaxY();
+ $scalingUp = $this->getScalingUp();
+ $maxScaleFactor = $this->getMaxScaleFactor();
+
+ if ($x < $maxX || $y < $maxY) {
+ if ($scalingUp) {
+ $scalefactor = $maxX / $x;
+ if ($scalefactor > $maxScaleFactor) {
+ return true;
+ }
} else {
- return $path;
+ return true;
}
}
+ return false;
}
/**
@@ -420,7 +450,7 @@ class Preview {
}
$fileId = $fileInfo->getId();
- $cached = $this->isCached();
+ $cached = $this->isCached($fileId);
if ($cached) {
$stream = $this->userView->fopen($cached, 'r');
@@ -434,13 +464,14 @@ class Preview {
if (is_null($this->preview)) {
$preview = null;
- foreach (self::$providers as $supportedMimetype => $provider) {
- if (!preg_match($supportedMimetype, $this->mimetype)) {
+ foreach (self::$providers as $supportedMimeType => $provider) {
+ if (!preg_match($supportedMimeType, $this->mimeType)) {
continue;
}
\OC_Log::write('core', 'Generating preview for "' . $file . '" with "' . get_class($provider) . '"', \OC_Log::DEBUG);
+ /** @var $provider Provider */
$preview = $provider->getThumbnail($file, $maxX, $maxY, $scalingUp, $this->fileView);
if (!($preview instanceof \OC_Image)) {
@@ -484,7 +515,6 @@ class Preview {
$this->getPreview();
}
$this->preview->show('image/png');
- return;
}
/**
@@ -493,7 +523,6 @@ class Preview {
*/
public function show() {
$this->showPreview();
- return;
}
/**
@@ -505,7 +534,7 @@ class Preview {
$x = $this->getMaxX();
$y = $this->getMaxY();
$scalingUp = $this->getScalingUp();
- $maxscalefactor = $this->getMaxScaleFactor();
+ $maxScaleFactor = $this->getMaxScaleFactor();
if (!($image instanceof \OC_Image)) {
\OC_Log::write('core', '$this->preview is not an instance of OC_Image', \OC_Log::DEBUG);
@@ -514,16 +543,16 @@ class Preview {
$image->fixOrientation();
- $realx = (int)$image->width();
- $realy = (int)$image->height();
+ $realX = (int)$image->width();
+ $realY = (int)$image->height();
- if ($x === $realx && $y === $realy) {
+ if ($x === $realX && $y === $realY) {
$this->preview = $image;
return;
}
- $factorX = $x / $realx;
- $factorY = $y / $realy;
+ $factorX = $x / $realX;
+ $factorY = $y / $realY;
if ($factorX >= $factorY) {
$factor = $factorX;
@@ -537,25 +566,25 @@ class Preview {
}
}
- if (!is_null($maxscalefactor)) {
- if ($factor > $maxscalefactor) {
- \OC_Log::write('core', 'scalefactor reduced from ' . $factor . ' to ' . $maxscalefactor, \OC_Log::DEBUG);
- $factor = $maxscalefactor;
+ if (!is_null($maxScaleFactor)) {
+ if ($factor > $maxScaleFactor) {
+ \OC_Log::write('core', 'scale factor reduced from ' . $factor . ' to ' . $maxScaleFactor, \OC_Log::DEBUG);
+ $factor = $maxScaleFactor;
}
}
- $newXsize = (int)($realx * $factor);
- $newYsize = (int)($realy * $factor);
+ $newXSize = (int)($realX * $factor);
+ $newYSize = (int)($realY * $factor);
- $image->preciseResize($newXsize, $newYsize);
+ $image->preciseResize($newXSize, $newYSize);
- if ($newXsize === $x && $newYsize === $y) {
+ if ($newXSize === $x && $newYSize === $y) {
$this->preview = $image;
return;
}
- if ($newXsize >= $x && $newYsize >= $y) {
- $cropX = floor(abs($x - $newXsize) * 0.5);
+ if ($newXSize >= $x && $newYSize >= $y) {
+ $cropX = floor(abs($x - $newXSize) * 0.5);
//don't crop previews on the Y axis, this sucks if it's a document.
//$cropY = floor(abs($y - $newYsize) * 0.5);
$cropY = 0;
@@ -566,36 +595,36 @@ class Preview {
return;
}
- if ($newXsize < $x || $newYsize < $y) {
- if ($newXsize > $x) {
- $cropX = floor(($newXsize - $x) * 0.5);
- $image->crop($cropX, 0, $x, $newYsize);
+ if ($newXSize < $x || $newYSize < $y) {
+ if ($newXSize > $x) {
+ $cropX = floor(($newXSize - $x) * 0.5);
+ $image->crop($cropX, 0, $x, $newYSize);
}
- if ($newYsize > $y) {
- $cropY = floor(($newYsize - $y) * 0.5);
- $image->crop(0, $cropY, $newXsize, $y);
+ if ($newYSize > $y) {
+ $cropY = floor(($newYSize - $y) * 0.5);
+ $image->crop(0, $cropY, $newXSize, $y);
}
- $newXsize = (int)$image->width();
- $newYsize = (int)$image->height();
+ $newXSize = (int)$image->width();
+ $newYSize = (int)$image->height();
//create transparent background layer
- $backgroundlayer = imagecreatetruecolor($x, $y);
- $white = imagecolorallocate($backgroundlayer, 255, 255, 255);
- imagefill($backgroundlayer, 0, 0, $white);
+ $backgroundLayer = imagecreatetruecolor($x, $y);
+ $white = imagecolorallocate($backgroundLayer, 255, 255, 255);
+ imagefill($backgroundLayer, 0, 0, $white);
$image = $image->resource();
- $mergeX = floor(abs($x - $newXsize) * 0.5);
- $mergeY = floor(abs($y - $newYsize) * 0.5);
+ $mergeX = floor(abs($x - $newXSize) * 0.5);
+ $mergeY = floor(abs($y - $newYSize) * 0.5);
- imagecopy($backgroundlayer, $image, $mergeX, $mergeY, 0, 0, $newXsize, $newYsize);
+ imagecopy($backgroundLayer, $image, $mergeX, $mergeY, 0, 0, $newXSize, $newYSize);
//$black = imagecolorallocate(0,0,0);
//imagecolortransparent($transparentlayer, $black);
- $image = new \OC_Image($backgroundlayer);
+ $image = new \OC_Image($backgroundLayer);
$this->preview = $image;
return;
@@ -630,6 +659,7 @@ class Preview {
$class = $provider['class'];
$options = $provider['options'];
+ /** @var $object Provider */
$object = new $class($options);
self::$providers[$object->getMimeType()] = $object;
@@ -676,9 +706,9 @@ class Preview {
}
/**
- * @param string $mimetype
+ * @param string $mimeType
*/
- public static function isMimeSupported($mimetype) {
+ public static function isMimeSupported($mimeType) {
if (!\OC_Config::getValue('enable_previews', true)) {
return false;
}
@@ -690,8 +720,8 @@ class Preview {
//remove last element because it has the mimetype *
$providers = array_slice(self::$providers, 0, -1);
- foreach ($providers as $supportedMimetype => $provider) {
- if (preg_match($supportedMimetype, $mimetype)) {
+ foreach ($providers as $supportedMimeType => $provider) {
+ if (preg_match($supportedMimeType, $mimeType)) {
return true;
}
}
diff --git a/lib/private/preview/movies.php b/lib/private/preview/movies.php
index 7e0ff51ad2e..72ccfadc6e9 100644
--- a/lib/private/preview/movies.php
+++ b/lib/private/preview/movies.php
@@ -42,7 +42,6 @@ if (!\OC_Util::runningOnWindows()) {
public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) {
// TODO: use proc_open() and stream the source file ?
$absPath = \OC_Helper::tmpFile();
- $tmpPath = \OC_Helper::tmpFile();
$handle = $fileview->fopen($path, 'rb');
@@ -51,14 +50,39 @@ if (!\OC_Util::runningOnWindows()) {
$firstmb = stream_get_contents($handle, 5242880);
file_put_contents($absPath, $firstmb);
+ $result = $this->generateThumbNail($maxX, $maxY, $absPath, 5);
+ if ($result === false) {
+ $result = $this->generateThumbNail($maxX, $maxY, $absPath, 1);
+ if ($result === false) {
+ $result = $this->generateThumbNail($maxX, $maxY, $absPath, 0);
+ }
+ }
+
+ unlink($absPath);
+
+
+ return $result;
+ }
+
+ /**
+ * @param int $maxX
+ * @param int $maxY
+ * @param string $absPath
+ * @param string $tmpPath
+ * @param int $second
+ * @return bool|\OC_Image
+ */
+ private function generateThumbNail($maxX, $maxY, $absPath, $second)
+ {
+ $tmpPath = \OC_Helper::tmpFile();
+
if (self::$avconvBinary) {
- $cmd = self::$avconvBinary . ' -an -y -ss 5'.
+ $cmd = self::$avconvBinary . ' -an -y -ss ' . escapeshellarg($second) .
' -i ' . escapeshellarg($absPath) .
' -f mjpeg -vframes 1 -vsync 1 ' . escapeshellarg($tmpPath) .
' > /dev/null 2>&1';
- }
- else {
- $cmd = self::$ffmpegBinary . ' -y -ss 5' .
+ } else {
+ $cmd = self::$ffmpegBinary . ' -y -ss ' . escapeshellarg($second) .
' -i ' . escapeshellarg($absPath) .
' -f mjpeg -vframes 1' .
' -s ' . escapeshellarg($maxX) . 'x' . escapeshellarg($maxY) .
@@ -68,14 +92,13 @@ if (!\OC_Util::runningOnWindows()) {
exec($cmd, $output, $returnCode);
- unlink($absPath);
-
if ($returnCode === 0) {
$image = new \OC_Image();
$image->loadFromFile($tmpPath);
unlink($tmpPath);
return $image->valid() ? $image : false;
}
+ unlink($tmpPath);
return false;
}
}
diff --git a/lib/private/server.php b/lib/private/server.php
index 3517d7b3548..5d90a0b19fc 100644
--- a/lib/private/server.php
+++ b/lib/private/server.php
@@ -35,6 +35,13 @@ class Server extends SimpleContainer implements IServerContainer {
$requesttoken = false;
}
+ if (defined('PHPUNIT_RUN') && PHPUNIT_RUN
+ && in_array('fakeinput', stream_get_wrappers())) {
+ $stream = 'fakeinput://data';
+ } else {
+ $stream = 'php://input';
+ }
+
return new Request(
array(
'get' => $_GET,
@@ -48,7 +55,7 @@ class Server extends SimpleContainer implements IServerContainer {
: null,
'urlParams' => $urlParams,
'requesttoken' => $requesttoken,
- )
+ ), $stream
);
});
$this->registerService('PreviewManager', function($c) {
diff --git a/lib/private/share/share.php b/lib/private/share/share.php
index 3bc07b43b4c..d4f08e8e016 100644
--- a/lib/private/share/share.php
+++ b/lib/private/share/share.php
@@ -431,6 +431,16 @@ class Share extends \OC\Share\Constants {
$itemSourceName = $itemSource;
}
+ // verify that the file exists before we try to share it
+ if ($itemType === 'file' or $itemType === 'folder') {
+ $path = \OC\Files\Filesystem::getPath($itemSource);
+ if (!$path) {
+ $message = 'Sharing ' . $itemSourceName . ' failed, because the file does not exist';
+ \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
+ throw new \Exception($message);
+ }
+ }
+
// Verify share type and sharing conditions are met
if ($shareType === self::SHARE_TYPE_USER) {
if ($shareWith == $uidOwner) {
diff --git a/lib/private/template.php b/lib/private/template.php
index c6851c6cc8d..610d5fbc8e5 100644
--- a/lib/private/template.php
+++ b/lib/private/template.php
@@ -64,29 +64,6 @@ class OC_Template extends \OC\Template\Base {
$this->path = $path;
parent::__construct($template, $requesttoken, $l10n, $themeDefaults);
-
- // Some headers to enhance security
- header('X-XSS-Protection: 1; mode=block'); // Enforce browser based XSS filters
- header('X-Content-Type-Options: nosniff'); // Disable sniffing the content type for IE
-
- // iFrame Restriction Policy
- $xFramePolicy = OC_Config::getValue('xframe_restriction', true);
- if($xFramePolicy) {
- header('X-Frame-Options: Sameorigin'); // Disallow iFraming from other domains
- }
-
- // Content Security Policy
- // If you change the standard policy, please also change it in config.sample.php
- $policy = OC_Config::getValue('custom_csp_policy',
- 'default-src \'self\'; '
- .'script-src \'self\' \'unsafe-eval\'; '
- .'style-src \'self\' \'unsafe-inline\'; '
- .'frame-src *; '
- .'img-src *; '
- .'font-src \'self\' data:; '
- .'media-src *');
- header('Content-Security-Policy:'.$policy); // Standard
-
}
/**
diff --git a/lib/private/template/functions.php b/lib/private/template/functions.php
index a72d41f72da..3c42d441efa 100644
--- a/lib/private/template/functions.php
+++ b/lib/private/template/functions.php
@@ -7,16 +7,17 @@
*/
/**
- * Prints an XSS escaped string
- * @param string $string the string which will be escaped and printed
+ * Prints a sanitized string
+ * @param string|array $string the string which will be escaped and printed
*/
function p($string) {
print(OC_Util::sanitizeHTML($string));
}
/**
- * Prints an unescaped string
- * @param string $string the string which will be printed as it is
+ * Prints an unsanitized string - usage of this function may result into XSS.
+ * Consider using p() instead.
+ * @param string|array $string the string which will be printed as it is
*/
function print_unescaped($string) {
print($string);
diff --git a/lib/private/templatelayout.php b/lib/private/templatelayout.php
index af17adb11c6..0c0c8d9c8d7 100644
--- a/lib/private/templatelayout.php
+++ b/lib/private/templatelayout.php
@@ -66,7 +66,7 @@ class OC_TemplateLayout extends OC_Template {
}
$versionParameter = '?v=' . md5(implode(OC_Util::getVersion()));
- $useAssetPipeline = OC_Config::getValue('asset-pipeline.enabled', false);
+ $useAssetPipeline = $this->isAssetPipelineEnabled();
if ($useAssetPipeline) {
$this->append( 'jsfiles', OC_Helper::linkToRoute('js_config') . $versionParameter);
@@ -179,4 +179,33 @@ class OC_TemplateLayout extends OC_Template {
sort($files);
return hash('md5', implode('', $files));
}
+
+ /**
+ * @return bool
+ */
+ private function isAssetPipelineEnabled() {
+ // asset management enabled?
+ $useAssetPipeline = OC_Config::getValue('asset-pipeline.enabled', false);
+ if (!$useAssetPipeline) {
+ return false;
+ }
+
+ // assets folder exists?
+ $assetDir = \OC::$SERVERROOT . '/assets';
+ if (!is_dir($assetDir)) {
+ if (!mkdir($assetDir)) {
+ \OCP\Util::writeLog('assets',
+ "Folder <$assetDir> does not exist and/or could not be generated.", \OCP\Util::ERROR);
+ return false;
+ }
+ }
+
+ // assets folder can be accessed?
+ if (!touch($assetDir."/.oc")) {
+ \OCP\Util::writeLog('assets',
+ "Folder <$assetDir> could not be accessed.", \OCP\Util::ERROR);
+ return false;
+ }
+ return $useAssetPipeline;
+ }
}
diff --git a/lib/private/user/manager.php b/lib/private/user/manager.php
index a2ad9d17702..14698452e88 100644
--- a/lib/private/user/manager.php
+++ b/lib/private/user/manager.php
@@ -175,13 +175,6 @@ class Manager extends PublicEmitter {
if (is_array($backendUsers)) {
foreach ($backendUsers as $uid) {
$users[] = $this->getUserObject($uid, $backend);
- if (!is_null($limit)) {
- $limit--;
- }
- if (!is_null($offset) and $offset > 0) {
- $offset--;
- }
-
}
}
}
@@ -211,13 +204,6 @@ class Manager extends PublicEmitter {
if (is_array($backendUsers)) {
foreach ($backendUsers as $uid => $displayName) {
$users[] = $this->getUserObject($uid, $backend);
- if (!is_null($limit)) {
- $limit--;
- }
- if (!is_null($offset) and $offset > 0) {
- $offset--;
- }
-
}
}
}
diff --git a/lib/private/util.php b/lib/private/util.php
index a744644b39c..e20de308e87 100755
--- a/lib/private/util.php
+++ b/lib/private/util.php
@@ -902,6 +902,8 @@ class OC_Util {
// for this self test we don't care if the ssl certificate is self signed and the peer cannot be verified.
$client->setVerifyPeer(false);
+ // also don't care if the host can't be verified
+ $client->setVerifyHost(0);
$return = true;
try {
diff --git a/lib/public/appframework/http/jsonresponse.php b/lib/public/appframework/http/jsonresponse.php
index 6628c4514d9..6d029b7464a 100644
--- a/lib/public/appframework/http/jsonresponse.php
+++ b/lib/public/appframework/http/jsonresponse.php
@@ -49,7 +49,6 @@ class JSONResponse extends Response {
public function __construct($data=array(), $statusCode=Http::STATUS_OK) {
$this->data = $data;
$this->setStatus($statusCode);
- $this->addHeader('X-Content-Type-Options', 'nosniff');
$this->addHeader('Content-type', 'application/json; charset=utf-8');
}