From 24dc0ccf906696b461a564e8cccc884afb9d3920 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim=20D=C3=BCsterhus?= Date: Mon, 6 Jul 2020 17:01:34 +0200 Subject: [PATCH] Return relative paths for logos uploaded in style editor Resolves #3283 --- .../install/files/acp/js/WCF.ACP.Style.js | 60 ++++++++-------- .../install/files/acp/templates/styleAdd.tpl | 4 +- .../lib/data/style/StyleAction.class.php | 69 ++++--------------- 3 files changed, 46 insertions(+), 87 deletions(-) diff --git a/wcfsetup/install/files/acp/js/WCF.ACP.Style.js b/wcfsetup/install/files/acp/js/WCF.ACP.Style.js index ee3a479bde..e58d41b082 100644 --- a/wcfsetup/install/files/acp/js/WCF.ACP.Style.js +++ b/wcfsetup/install/files/acp/js/WCF.ACP.Style.js @@ -198,18 +198,11 @@ WCF.ACP.Style.LogoUpload = WCF.Upload.extend({ */ _tmpHash: '', - /** - * absolute path to WCF directory - * @var string - */ - _wcfPath: '', - /** * @see WCF.Upload.init() */ - init: function(tmpHash, wcfPath) { + init: function(tmpHash) { this._tmpHash = tmpHash; - this._wcfPath = wcfPath; this._button = $('#uploadLogo'); this._image = $('#styleLogo'); @@ -232,12 +225,9 @@ WCF.ACP.Style.LogoUpload = WCF.Upload.extend({ var $src = this._pageLogo.val(); if ($src.length) { if (!$src.match(/^https?:\/\//)) { - var $path = this._imagePath.val(); - if (!$path) { - $path = 'images/'; - } + var $path = this._getImagePath(); - $path = this._wcfPath + $path.replace(/^\/?images\/?/, ''); + $path = WCF_PATH + $path; if ($path.substr(-1) !== '/') { $path += '/'; } @@ -255,6 +245,13 @@ WCF.ACP.Style.LogoUpload = WCF.Upload.extend({ this._image.attr('src', $src + '?timestamp=' + Date.now()); }, + /** + * Returns the style's image path. + */ + _getImagePath: function () { + return this._imagePath.val() || 'images/'; + }, + /** * @see WCF.Upload._initFile() */ @@ -267,7 +264,9 @@ WCF.ACP.Style.LogoUpload = WCF.Upload.extend({ */ _getParameters: function() { return { - tmpHash: this._tmpHash + tmpHash: this._tmpHash, + imagePath: this._getImagePath(), + type: 'styleLogo', }; }, @@ -277,8 +276,8 @@ WCF.ACP.Style.LogoUpload = WCF.Upload.extend({ _success: function(uploadID, data) { if (data.returnValues.url) { // show image - this._image.attr('src', data.returnValues.url + '?timestamp=' + Date.now()); this._pageLogo.val(data.returnValues.url); + this._updateLogo(); // hide error this._button.next('.innerError').remove(); @@ -347,25 +346,18 @@ WCF.ACP.Style.LogoUploadMobile = WCF.Upload.extend({ */ _tmpHash: '', - /** - * absolute path to WCF directory - * @var string - */ - _wcfPath: '', - /** * @see WCF.Upload.init() */ - init: function(tmpHash, wcfPath) { + init: function(tmpHash) { this._tmpHash = tmpHash; - this._wcfPath = wcfPath; this._button = $('#uploadLogoMobile'); this._image = $('#styleLogoMobile'); this._imagePath = $('#imagePath'); this._pageLogo = $('#pageLogoMobile'); - this._super(this._button, undefined, 'wcf\\data\\style\\StyleAction', { action: 'uploadLogoMobile' }); + this._super(this._button, undefined, 'wcf\\data\\style\\StyleAction', { action: 'uploadLogo' }); if (!this._image.attr('src').length) { this._updateLogo(); @@ -381,12 +373,9 @@ WCF.ACP.Style.LogoUploadMobile = WCF.Upload.extend({ var $src = this._pageLogo.val(); if ($src.length) { if (!$src.match(/^https?:\/\//)) { - var $path = this._imagePath.val(); - if (!$path) { - $path = 'images/'; - } + var $path = this._getImagePath(); - $path = this._wcfPath + $path.replace(/^\/?images\/?/, ''); + $path = WCF_PATH + $path; if ($path.substr(-1) !== '/') { $path += '/'; } @@ -402,6 +391,13 @@ WCF.ACP.Style.LogoUploadMobile = WCF.Upload.extend({ this._image.attr('src', $src + '?timestamp=' + Date.now()); }, + /** + * Returns the style's image path. + */ + _getImagePath: function () { + return this._imagePath.val() || 'images/'; + }, + /** * @see WCF.Upload._initFile() */ @@ -414,7 +410,9 @@ WCF.ACP.Style.LogoUploadMobile = WCF.Upload.extend({ */ _getParameters: function() { return { - tmpHash: this._tmpHash + tmpHash: this._tmpHash, + imagePath: this._getImagePath(), + type: 'styleLogo-mobile', }; }, @@ -424,8 +422,8 @@ WCF.ACP.Style.LogoUploadMobile = WCF.Upload.extend({ _success: function(uploadID, data) { if (data.returnValues.url) { // show image - this._image.attr('src', data.returnValues.url + '?timestamp=' + Date.now()); this._pageLogo.val(data.returnValues.url); + this._updateLogo(); // hide error this._button.next('.innerError').remove(); diff --git a/wcfsetup/install/files/acp/templates/styleAdd.tpl b/wcfsetup/install/files/acp/templates/styleAdd.tpl index a80ad128d5..d848ffb462 100644 --- a/wcfsetup/install/files/acp/templates/styleAdd.tpl +++ b/wcfsetup/install/files/acp/templates/styleAdd.tpl @@ -55,8 +55,8 @@ 'wcf.acp.style.favicon.error.invalidExtension': '{lang}wcf.acp.style.favicon.error.invalidExtension{/lang}', 'wcf.acp.style.image.error.invalidExtension': '{lang}wcf.acp.style.image.error.invalidExtension{/lang}' }); - new WCF.ACP.Style.LogoUpload('{$tmpHash}', '{@$__wcf->getPath()}images/'); - new WCF.ACP.Style.LogoUploadMobile('{$tmpHash}', '{@$__wcf->getPath()}images/'); + new WCF.ACP.Style.LogoUpload('{$tmpHash}'); + new WCF.ACP.Style.LogoUploadMobile('{$tmpHash}'); {if $action == 'edit'} new WCF.ACP.Style.CopyStyle({@$style->styleID}); diff --git a/wcfsetup/install/files/lib/data/style/StyleAction.class.php b/wcfsetup/install/files/lib/data/style/StyleAction.class.php index e314baf4c6..0450bf0008 100644 --- a/wcfsetup/install/files/lib/data/style/StyleAction.class.php +++ b/wcfsetup/install/files/lib/data/style/StyleAction.class.php @@ -509,23 +509,32 @@ BROWSERCONFIG; $file = $files[0]; try { + $relativePath = FileUtil::unifyDirSeparator(FileUtil::getRelativePath(WCF_DIR.'images/', WCF_DIR.$this->parameters['imagePath'])); + if (strpos($relativePath, '../') !== false) { + throw new UserInputException('imagePath', 'invalid'); + } + + if ($this->parameters['type'] !== 'styleLogo' && $this->parameters['type'] !== 'styleLogo-mobile') { + throw new UserInputException('type', 'invalid'); + } + if (!$file->getValidationErrorType()) { // shrink avatar if necessary $fileLocation = $file->getLocation(); + $basename = $this->parameters['type'].'-'.$this->parameters['tmpHash'].'.'.$file->getFileExtension();; + $target = WCF_DIR.$this->parameters['imagePath'].'/'.$basename; + // move uploaded file - if (@copy($fileLocation, WCF_DIR.'images/styleLogo-'.$this->parameters['tmpHash'].'.'.$file->getFileExtension())) { + if (@copy($fileLocation, $target)) { @unlink($fileLocation); - // store extension within session variables - WCF::getSession()->register('styleLogo-'.$this->parameters['tmpHash'], $file->getFileExtension()); - // get logo size - list($width, $height) = getimagesize(WCF_DIR.'images/styleLogo-'.$this->parameters['tmpHash'].'.'.$file->getFileExtension()); + list($width, $height) = getimagesize($target); // return result return [ - 'url' => WCF::getPath().'images/styleLogo-'.$this->parameters['tmpHash'].'.'.$file->getFileExtension(), + 'url' => $basename, 'width' => $width, 'height' => $height ]; @@ -542,54 +551,6 @@ BROWSERCONFIG; return ['errorType' => $file->getValidationErrorType()]; } - /** - * Validates parameters to update a mobile logo. - */ - public function validateUploadLogoMobile() { - $this->validateUpload(); - } - - /** - * Handles mobile logo upload. - * - * @return string[] - */ - public function uploadLogoMobile() { - // save files - /** @noinspection PhpUndefinedMethodInspection */ - /** @var UploadFile[] $files */ - $files = $this->parameters['__files']->getFiles(); - $file = $files[0]; - - try { - if (!$file->getValidationErrorType()) { - // shrink avatar if necessary - $fileLocation = $file->getLocation(); - - // move uploaded file - if (@copy($fileLocation, WCF_DIR.'images/styleLogo-mobile-'.$this->parameters['tmpHash'].'.'.$file->getFileExtension())) { - @unlink($fileLocation); - - // store extension within session variables - WCF::getSession()->register('styleLogo-mobile-'.$this->parameters['tmpHash'], $file->getFileExtension()); - - // return result - return [ - 'url' => WCF::getPath().'images/styleLogo-mobile-'.$this->parameters['tmpHash'].'.'.$file->getFileExtension() - ]; - } - else { - throw new UserInputException('image', 'uploadFailed'); - } - } - } - catch (UserInputException $e) { - $file->setValidationErrorType($e->getType()); - } - - return ['errorType' => $file->getValidationErrorType()]; - } - /** * Validates parameters to upload a favicon. * -- 2.20.1