Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMorris Jobke <hey@morrisjobke.de>2018-01-29 18:12:10 +0300
committerGitHub <noreply@github.com>2018-01-29 18:12:10 +0300
commit4fcdfbf5de5496cf1fc683b6a2f4c55764de8e02 (patch)
tree2daf3982a94dec5538b5defaecf5f86280ddad6c /lib
parent01482b32a171bb8529bc8baacbe764107e52e14c (diff)
parent5dbf73339542977698e1f3ae6d22624fab74fe3e (diff)
Merge pull request #8078 from nextcloud/theming-validate-scss
SCSS hardening
Diffstat (limited to 'lib')
-rw-r--r--lib/private/Template/SCSSCacher.php57
1 files changed, 41 insertions, 16 deletions
diff --git a/lib/private/Template/SCSSCacher.php b/lib/private/Template/SCSSCacher.php
index a4604425544..8830a651f36 100644
--- a/lib/private/Template/SCSSCacher.php
+++ b/lib/private/Template/SCSSCacher.php
@@ -57,12 +57,18 @@ class SCSSCacher {
/** @var IConfig */
protected $config;
+ /** @var \OC_Defaults */
+ private $defaults;
+
/** @var string */
protected $serverRoot;
/** @var ICache */
protected $depsCache;
+ /** @var null|string */
+ private $injectedVariables;
+
/**
* @param ILogger $logger
* @param Factory $appDataFactory
@@ -90,12 +96,14 @@ class SCSSCacher {
/**
* Process the caching process if needed
+ *
* @param string $root Root path to the nextcloud installation
* @param string $file
* @param string $app The app name
* @return boolean
+ * @throws NotPermittedException
*/
- public function process($root, $file, $app) {
+ public function process(string $root, string $file, string $app): bool {
$path = explode('/', $root . '/' . $file);
$fileNameSCSS = array_pop($path);
@@ -123,7 +131,7 @@ class SCSSCacher {
* @param $fileName
* @return ISimpleFile
*/
- public function getCachedCSS($appName, $fileName) {
+ public function getCachedCSS(string $appName, string $fileName): ISimpleFile {
$folder = $this->appData->getFolder($appName);
return $folder->getFile($this->prependBaseurlPrefix($fileName));
}
@@ -134,7 +142,7 @@ class SCSSCacher {
* @param ISimpleFolder $folder
* @return boolean
*/
- private function isCached($fileNameCSS, ISimpleFolder $folder) {
+ private function isCached(string $fileNameCSS, ISimpleFolder $folder) {
try {
$cachedFile = $folder->getFile($fileNameCSS);
if ($cachedFile->getSize() > 0) {
@@ -148,13 +156,14 @@ class SCSSCacher {
}
$deps = json_decode($deps, true);
- foreach ($deps as $file=>$mtime) {
+ foreach ((array)$deps as $file=>$mtime) {
if (!file_exists($file) || filemtime($file) > $mtime) {
return false;
}
}
+ return true;
}
- return true;
+ return false;
} catch(NotFoundException $e) {
return false;
}
@@ -164,7 +173,7 @@ class SCSSCacher {
* Check if the variables file has changed
* @return bool
*/
- private function variablesChanged() {
+ private function variablesChanged(): bool {
$injectedVariables = $this->getInjectedVariables();
if($this->config->getAppValue('core', 'scss.variables') !== md5($injectedVariables)) {
$this->resetCache();
@@ -176,14 +185,16 @@ class SCSSCacher {
/**
* Cache the file with AppData
+ *
* @param string $path
* @param string $fileNameCSS
* @param string $fileNameSCSS
* @param ISimpleFolder $folder
* @param string $webDir
* @return boolean
+ * @throws NotPermittedException
*/
- private function cache($path, $fileNameCSS, $fileNameSCSS, ISimpleFolder $folder, $webDir) {
+ private function cache(string $path, string $fileNameCSS, string $fileNameSCSS, ISimpleFolder $folder, string $webDir) {
$scss = new Compiler();
$scss->setImportPaths([
$path,
@@ -250,13 +261,14 @@ class SCSSCacher {
* We need to regenerate all files when variables change
*/
private function resetCache() {
+ $this->injectedVariables = null;
$appDirectory = $this->appData->getDirectoryListing();
if(empty($appDirectory)){
return;
}
foreach ($appDirectory as $folder) {
foreach ($folder->getDirectoryListing() as $file) {
- if (substr($file->getName(), -3) === "css" || substr($file->getName(), -4) === "deps") {
+ if (substr($file->getName(), -3) === 'css' || substr($file->getName(), -4) === 'deps') {
$file->delete();
}
}
@@ -266,11 +278,24 @@ class SCSSCacher {
/**
* @return string SCSS code for variables from OC_Defaults
*/
- private function getInjectedVariables() {
+ private function getInjectedVariables(): string {
+ if ($this->injectedVariables !== null) {
+ return $this->injectedVariables;
+ }
$variables = '';
foreach ($this->defaults->getScssVariables() as $key => $value) {
$variables .= '$' . $key . ': ' . $value . ';';
}
+
+ // check for valid variables / otherwise fall back to defaults
+ try {
+ $scss = new Compiler();
+ $scss->compile($variables);
+ $this->injectedVariables = $variables;
+ } catch (ParserException $e) {
+ $this->logger->error($e, ['app' => 'core']);
+ }
+
return $variables;
}
@@ -280,8 +305,8 @@ class SCSSCacher {
* @param string $webDir
* @return string
*/
- private function rebaseUrls($css, $webDir) {
- $re = '/url\([\'"]([\.\w?=\/-]*)[\'"]\)/x';
+ private function rebaseUrls(string $css, string $webDir): string {
+ $re = '/url\([\'"]([^\/][\.\w?=\/-]*)[\'"]\)/x';
$subst = 'url(\''.$webDir.'/$1\')';
return preg_replace($re, $subst, $css);
}
@@ -292,20 +317,20 @@ class SCSSCacher {
* @param string $fileName
* @return string
*/
- public function getCachedSCSS($appName, $fileName) {
+ public function getCachedSCSS(string $appName, string $fileName): string {
$tmpfileLoc = explode('/', $fileName);
$fileName = array_pop($tmpfileLoc);
$fileName = $this->prependBaseurlPrefix(str_replace('.scss', '.css', $fileName));
- return substr($this->urlGenerator->linkToRoute('core.Css.getCss', array('fileName' => $fileName, 'appName' => $appName)), strlen(\OC::$WEBROOT) + 1);
+ return substr($this->urlGenerator->linkToRoute('core.Css.getCss', ['fileName' => $fileName, 'appName' => $appName]), strlen(\OC::$WEBROOT) + 1);
}
/**
* Prepend hashed base url to the css file
- * @param $cssFile
+ * @param string$cssFile
* @return string
*/
- private function prependBaseurlPrefix($cssFile) {
+ private function prependBaseurlPrefix(string $cssFile): string {
$frontendController = ($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true');
return substr(md5($this->urlGenerator->getBaseUrl() . $frontendController), 0, 8) . '-' . $cssFile;
}
@@ -318,7 +343,7 @@ class SCSSCacher {
* @param string $webRoot the nextcloud installation root path
* @return string the webDir
*/
- private function getWebDir($path, $appName, $serverRoot, $webRoot) {
+ private function getWebDir(string $path, string $appName, string $serverRoot, string $webRoot): string {
// Detect if path is within server root AND if path is within an app path
if ( strpos($path, $serverRoot) === false && $appWebPath = \OC_App::getAppWebPath($appName)) {
// Get the file path within the app directory