Skip to content

Commit

Permalink
Bug/16733 when importing a theme bigger in size than the allowed php.…
Browse files Browse the repository at this point in the history
…ini settings, there is no proper description of the error (#1633)

* Fixed issue #16733: When importing a theme bigger in size than the allowed PHP.ini settings, there is no proper description of the error

Adding helper functions for checking uploads filesize

* Fixed issue #16733: When importing a theme bigger in size than the allowed PHP.ini settings, there is no proper description of the error

Applying fix on
- Theme import (Themes list and Theme editor)
- File upload in Theme editor (uploading files to a theme)
- Image upload (in global theme options)
- Image upload (in survey theme options

* Fixed issue #16733: When importing a theme bigger in size than the allowed PHP.ini settings, there is no proper description of the error

Creating Uploadhelper and moving helper functions to class methods.
  • Loading branch information
gabrieljenik committed Nov 10, 2020
1 parent e2b704e commit eef2022
Show file tree
Hide file tree
Showing 9 changed files with 301 additions and 179 deletions.
26 changes: 6 additions & 20 deletions application/controllers/admin/surveyadmin.php
Expand Up @@ -2336,9 +2336,14 @@ public function applythemeoptions($iSurveyID = 0)
*/
public function uploadimagefile()
{
$debug = [$_FILES];
// Check file size and render JSON on error.
// This is done before checking the survey permissions because, if the max POST size was exceeded,
// there is no Survey ID to check for permissions, so the error could be misleading.
LSUploadHelper::checkUploadedFileSizeAndRenderJson('file', $debug);

$iSurveyID = Yii::app()->request->getPost('surveyid');
$success = false;
$debug = [];
if(!Permission::model()->hasSurveyPermission($iSurveyID, 'surveycontent', 'update')) {
return Yii::app()->getController()->renderPartial(
'/admin/super/_renderJson',
Expand All @@ -2347,25 +2352,6 @@ public function uploadimagefile()
false
);
}
$debug[] = $_FILES;
if(empty($_FILES)) {
$uploadresult = gT("No file was uploaded.");
return Yii::app()->getController()->renderPartial(
'/admin/super/_renderJson',
array('data' => ['success' => $success, 'message' => $uploadresult, 'debug' => $debug]),
false,
false
);
}
if ($_FILES['file']['error'] == 1 || $_FILES['file']['error'] == 2) {
$uploadresult = sprintf(gT("Sorry, this file is too large. Only files up to %01.2f MB are allowed."), getMaximumFileUploadSize() / 1024 / 1024);
return Yii::app()->getController()->renderPartial(
'/admin/super/_renderJson',
array('data' => ['success' => $success, 'message' => $uploadresult, 'debug' => $debug]),
false,
false
);
}
$checkImage = LSYii_ImageValidator::validateImage($_FILES["file"]);
if ($checkImage['check'] === false) {
return Yii::app()->getController()->renderPartial(
Expand Down
343 changes: 190 additions & 153 deletions application/controllers/admin/themes.php

Large diffs are not rendered by default.

99 changes: 99 additions & 0 deletions application/core/LSUploadHelper.php
@@ -0,0 +1,99 @@
<?php
/*
* LimeSurvey
* Copyright (C) 2020 The LimeSurvey Project Team / Carsten Schmitz
* All rights reserved.
* License: GNU/GPL License v2 or later, see LICENSE.php
* LimeSurvey is free software. This version may have been modified pursuant
* to the GNU General Public License, and as distributed it includes or
* is derivative of works licensed under the GNU General Public License or
* other free or open source software licenses.
* See COPYRIGHT.php for copyright notices and details.
*
*/

class LSUploadHelper
{
/**
* Check uploaded file size
*
* @param string $sFileName the name of the posted file
* @param mixed $customMaxSize maximum file upload size
*
* @throws Exception if the file is too large or no file is found.
*/
public static function checkUploadedFileSize($sFileName, $customMaxSize = null)
{
if (is_null($customMaxSize)) {
$iMaximumSize = getMaximumFileUploadSize();
} else {
$iMaximumSize = min((int) $customMaxSize, getMaximumFileUploadSize());
}

// When 'post_max_size' is exceeded $_POST and $_FILES are empty.
// There is no way to confirm if the superglobals are empty because 'post_max_size' was
// exceeded, or because nothing was posted.
if (empty($_POST) && empty($_FILES)) {
throw new \Exception(
sprintf(
gT("No file was uploaded or the request exceeded %01.2f MB."),
convertPHPSizeToBytes(ini_get('post_max_size')) / 1024 / 1024
)
);
}

if (!isset($_FILES[$sFileName])) {
throw new \Exception(gT("File not found."));
}

$iFileSize = $_FILES[$sFileName]['size'];

if ($iFileSize > $iMaximumSize || $_FILES[$sFileName]['error'] == 1 || $_FILES[$sFileName]['error'] == 2) {
throw new \Exception(
sprintf(
gT("Sorry, this file is too large. Only files up to %01.2f MB are allowed."),
$iMaximumSize / 1024 / 1024
)
);
}
}

/**
* Check uploaded file size. Redirects to the specified URL on failure.
*
* @param string $sFileName the name of the posted file
* @param mixed $redirectUrl the URL to redirect on failure
* @param mixed $customMaxSize maximum file upload size
*/
public static function checkUploadedFileSizeAndRedirect($sFileName, $redirectUrl, $customMaxSize = null)
{
try {
self::checkUploadedFileSize($sFileName, $customMaxSize);
} catch (Exception $ex) {
Yii::app()->setFlashMessage($ex->getMessage(), 'error');
App()->getController()->redirect($redirectUrl);
}
}

/**
* Check uploaded file size. Renders JSON on failure.
*
* @param string $sFileName the name of the posted file
* @param array $debugInfo the URL to redirect on failure
* @param mixed $customMaxSize maximum file upload size
*/
public static function checkUploadedFileSizeAndRenderJson($sFileName, $debugInfo = [], $customMaxSize = null)
{
try {
self::checkUploadedFileSize($sFileName, $customMaxSize);
} catch (Exception $ex) {
$error = $ex->getMessage();
return Yii::app()->getController()->renderPartial(
'/admin/super/_renderJson',
array('data' => ['success' => 'error', 'message' => $error, 'debug' => $debugInfo]),
false,
false
);
}
}
}
2 changes: 1 addition & 1 deletion application/views/admin/themeoptions/import_modal.php
Expand Up @@ -7,7 +7,7 @@
<div class="modal fade" tabindex="-1" role="dialog" id="importModal">
<div class="modal-dialog">
<div class="modal-content">
<?php echo CHtml::form(array('admin/themes/sa/upload'), 'post', array('id'=>'importtemplate', 'name'=>'importtemplate', 'enctype'=>'multipart/form-data', 'onsubmit'=>'return window.LS.validatefilename(this,"'.gT('Please select a file to import!', 'js').'");')); ?>
<?php echo CHtml::form(array('admin/themes/sa/templateupload'), 'post', array('id'=>'importtemplate', 'name'=>'importtemplate', 'enctype'=>'multipart/form-data', 'onsubmit'=>'return window.LS.validatefilename(this,"'.gT('Please select a file to import!', 'js').'");')); ?>
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<div class="modal-title h4">
Expand Down
2 changes: 1 addition & 1 deletion application/views/admin/themeoptions/update.php
Expand Up @@ -144,7 +144,7 @@
<?php printf(gT("Upload an image (maximum size: %d MB):"),getMaximumFileUploadSize()/1024/1024); ?>
</div>
<div class="col-sm-6">
<?php echo TbHtml::form(array('admin/themes/sa/upload'), 'post', array('id'=>'uploadimage', 'name'=>'uploadimage', 'enctype'=>'multipart/form-data')); ?>
<?php echo TbHtml::form(array('admin/themes/sa/templateuploadimagefile'), 'post', array('id'=>'uploadimage', 'name'=>'uploadimage', 'enctype'=>'multipart/form-data')); ?>
<span id="fileselector">
<label class="btn btn-default col-xs-8" for="upload_image">
<input class="hidden" id="upload_image" name="upload_image" type="file" >
Expand Down
2 changes: 1 addition & 1 deletion application/views/admin/themes/importform_view.php
@@ -1,7 +1,7 @@


<div class="pagetitle h3"><?php eT("Upload template file") ?></div>
<?php echo CHtml::form(array('admin/themes/sa/upload'), 'post', array('id'=>'importtemplate', 'name'=>'importtemplate', 'enctype'=>'multipart/form-data', 'onsubmit'=>'return window.LS.validatefilename(this,"'.gT('Please select a file to import!', 'js').'");')); ?>
<?php echo CHtml::form(array('admin/themes/sa/templateupload'), 'post', array('id'=>'importtemplate', 'name'=>'importtemplate', 'enctype'=>'multipart/form-data', 'onsubmit'=>'return window.LS.validatefilename(this,"'.gT('Please select a file to import!', 'js').'");')); ?>
<input type='hidden' name='lid' value='$lid' />
<input type='hidden' name='action' value='templateupload' />
<div class="form-group">
Expand Down
2 changes: 1 addition & 1 deletion themes/survey/bootswatch/options/options.twig
Expand Up @@ -324,7 +324,7 @@
{{ sprintf( gT("Upload an image (maximum size: %d MB):"), (templateConfiguration.maxFileSize/1024/1024) ) }}
</div>
<div class="col-sm-6">
{{ C.Html.form(createUrl('/admin/themes/sa/upload'), 'post', { 'id' : 'upload_frontend', 'name' : 'upload_frontend', 'enctype' :'multipart/form-data' }) }}
{{ C.Html.form(createUrl('/admin/themes/sa/templateuploadimagefile'), 'post', { 'id' : 'upload_frontend', 'name' : 'upload_frontend', 'enctype' :'multipart/form-data' }) }}
<span id="fileselector_frontend">
<label class="btn btn-default col-xs-8" for="upload_image_frontend">
<input class="hidden" id="upload_image_frontend" name="upload_image_frontend" type="file">
Expand Down
2 changes: 1 addition & 1 deletion themes/survey/fruity/options/options.twig
Expand Up @@ -1104,7 +1104,7 @@
{{ sprintf( gT("Upload an image (maximum size: %d MB):"), (templateConfiguration.maxFileSize/1024/1024) ) }}
</div>
<div class="col-sm-6">
{{ C.Html.form(createUrl('/admin/themes/sa/upload'), 'post', { 'id' : 'upload_frontend', 'name' : 'upload_frontend', 'enctype' :'multipart/form-data' }) }}
{{ C.Html.form(createUrl('/admin/themes/sa/templateuploadimagefile'), 'post', { 'id' : 'upload_frontend', 'name' : 'upload_frontend', 'enctype' :'multipart/form-data' }) }}
<span id="fileselector_frontend">
<label class="btn btn-default col-xs-8" for="upload_image_frontend">
<input class="hidden" id="upload_image_frontend" name="upload_image_frontend" type="file">
Expand Down
2 changes: 1 addition & 1 deletion themes/survey/vanilla/options/options.twig
Expand Up @@ -314,7 +314,7 @@
{{ sprintf( gT("Upload an image (maximum size: %d MB):"), (templateConfiguration.maxFileSize/1024/1024) ) }}
</div>
<div class="col-sm-6">
{{ C.Html.form(createUrl('/admin/themes/sa/upload'), 'post', { 'id' : 'upload_frontend', 'name' : 'upload_frontend', 'enctype' :'multipart/form-data' }) }}
{{ C.Html.form(createUrl('/admin/themes/sa/templateuploadimagefile'), 'post', { 'id' : 'upload_frontend', 'name' : 'upload_frontend', 'enctype' :'multipart/form-data' }) }}
<span id="fileselector_frontend">
<label class="btn btn-default col-xs-8" for="upload_image_frontend">
<input class="hidden" id="upload_image_frontend" name="upload_image_frontend" type="file">
Expand Down

0 comments on commit eef2022

Please sign in to comment.