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

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Giehl <stefan@matomo.org>2021-01-01 03:30:49 +0300
committerGitHub <noreply@github.com>2021-01-01 03:30:49 +0300
commit339b5cd33c5f47a2a67730b3bfb9eed210219585 (patch)
tree27cfd92572dc24465238e66bfb59e9dee0cd0e0b
parent52c573a0572f079c99bfa3331b8ef4164e199281 (diff)
Don't accept files that are bigger than the upload limit when uploading plugins (#16849)
* Don't accept files that are bigger than the upload limit when uploading plugins * improve / simplify code * adds some tests
-rw-r--r--core/SettingsServer.php60
-rw-r--r--plugins/CorePluginsAdmin/Controller.php2
-rw-r--r--plugins/CorePluginsAdmin/CorePluginsAdmin.php1
-rw-r--r--plugins/CorePluginsAdmin/angularjs/plugins/plugin-upload.directive.js3
-rw-r--r--plugins/CorePluginsAdmin/lang/en.json1
-rw-r--r--plugins/Marketplace/Controller.php2
-rw-r--r--plugins/Marketplace/templates/uploadPluginDialog.twig2
-rw-r--r--tests/PHPUnit/Unit/SettingsServerTest.php47
8 files changed, 102 insertions, 16 deletions
diff --git a/core/SettingsServer.php b/core/SettingsServer.php
index 6846502ac4..3f61670fd6 100644
--- a/core/SettingsServer.php
+++ b/core/SettingsServer.php
@@ -196,26 +196,12 @@ class SettingsServer
* Prior to PHP 5.2.1, or on Windows, --enable-memory-limit is not a
* compile-time default, so ini_get('memory_limit') may return false.
*
- * @see http://www.php.net/manual/en/faq.using.php#faq.using.shorthandbytes
* @return int|bool memory limit in megabytes, or false if there is no limit
*/
public static function getMemoryLimitValue()
{
if (($memory = ini_get('memory_limit')) > 0) {
- // handle shorthand byte options (case-insensitive)
- $shorthandByteOption = substr($memory, -1);
- switch ($shorthandByteOption) {
- case 'G':
- case 'g':
- return substr($memory, 0, -1) * 1024;
- case 'M':
- case 'm':
- return substr($memory, 0, -1);
- case 'K':
- case 'k':
- return substr($memory, 0, -1) / 1024;
- }
- return $memory / 1048576;
+ return self::getMegaBytesFromShorthandByte($memory);
}
// no memory limit
@@ -223,6 +209,50 @@ class SettingsServer
}
/**
+ * Get php post_max_size (in Megabytes)
+ *
+ * @return int|bool max upload size in megabytes, or false if there is no limit
+ */
+ public static function getPostMaxUploadSize()
+ {
+ if (($maxPostSize = ini_get('post_max_size')) > 0) {
+ return self::getMegaBytesFromShorthandByte($maxPostSize);
+ }
+
+ // no max upload size
+ return false;
+ }
+
+ /**
+ * @see http://www.php.net/manual/en/faq.using.php#faq.using.shorthandbytes
+ * @param $value
+ * @return false|float|int
+ */
+ private static function getMegaBytesFromShorthandByte($value)
+ {
+ $value = str_replace(' ', '', $value);
+
+ $shorthandByteOption = substr($value, -1);
+ switch ($shorthandByteOption) {
+ case 'G':
+ case 'g':
+ return substr($value, 0, -1) * 1024;
+ case 'M':
+ case 'm':
+ return substr($value, 0, -1);
+ case 'K':
+ case 'k':
+ return substr($value, 0, -1) / 1024;
+ }
+
+ if (is_numeric($value)) {
+ return (int) $value / 1048576;
+ }
+
+ return false;
+ }
+
+ /**
* Set maximum script execution time.
*
* @param int $executionTime max execution time in seconds (0 = no limit)
diff --git a/plugins/CorePluginsAdmin/Controller.php b/plugins/CorePluginsAdmin/Controller.php
index da005443f2..df3f1de171 100644
--- a/plugins/CorePluginsAdmin/Controller.php
+++ b/plugins/CorePluginsAdmin/Controller.php
@@ -28,6 +28,7 @@ use Piwik\Plugins\Marketplace\Controller as MarketplaceController;
use Piwik\Plugins\Marketplace\Plugins;
use Piwik\Settings\Storage\Backend\PluginSettingsTable;
use Piwik\SettingsPiwik;
+use Piwik\SettingsServer;
use Piwik\Translation\Translator;
use Piwik\Url;
use Piwik\Version;
@@ -236,6 +237,7 @@ class Controller extends Plugin\ControllerAdmin
}
$view->isPluginUploadEnabled = CorePluginsAdmin::isPluginUploadEnabled();
+ $view->uploadLimit = SettingsServer::getPostMaxUploadSize();
$view->installNonce = Nonce::getNonce(MarketplaceController::INSTALL_NONCE);
return $view;
diff --git a/plugins/CorePluginsAdmin/CorePluginsAdmin.php b/plugins/CorePluginsAdmin/CorePluginsAdmin.php
index c8a72cf488..aeef54b2db 100644
--- a/plugins/CorePluginsAdmin/CorePluginsAdmin.php
+++ b/plugins/CorePluginsAdmin/CorePluginsAdmin.php
@@ -72,6 +72,7 @@ class CorePluginsAdmin extends Plugin
public function getClientSideTranslationKeys(&$translations)
{
$translations[] = 'CorePluginsAdmin_NoZipFileSelected';
+ $translations[] = 'CorePluginsAdmin_FileExceedsUploadLimit';
$translations[] = 'CorePluginsAdmin_NoPluginSettings';
$translations[] = 'CoreAdminHome_PluginSettingsIntro';
$translations[] = 'CoreAdminHome_PluginSettingsSaveSuccess';
diff --git a/plugins/CorePluginsAdmin/angularjs/plugins/plugin-upload.directive.js b/plugins/CorePluginsAdmin/angularjs/plugins/plugin-upload.directive.js
index 741b561011..dff036c519 100644
--- a/plugins/CorePluginsAdmin/angularjs/plugins/plugin-upload.directive.js
+++ b/plugins/CorePluginsAdmin/angularjs/plugins/plugin-upload.directive.js
@@ -37,6 +37,9 @@
if (!fileName || '.zip' != fileName.slice(-4)) {
event.preventDefault();
alert(_pk_translate('CorePluginsAdmin_NoZipFileSelected'));
+ } else if ($zipFile.data('maxSize') > 0 && $zipFile[0].files[0].size > $zipFile.data('maxSize')*1048576) {
+ event.preventDefault();
+ alert(_pk_translate('CorePluginsAdmin_FileExceedsUploadLimit'));
}
});
};
diff --git a/plugins/CorePluginsAdmin/lang/en.json b/plugins/CorePluginsAdmin/lang/en.json
index 020b96d3f7..54f674b9b0 100644
--- a/plugins/CorePluginsAdmin/lang/en.json
+++ b/plugins/CorePluginsAdmin/lang/en.json
@@ -33,6 +33,7 @@
"MissingRequirementsNotice": "Please update %1$s %2$s to a newer version, %1$s %3$s is required.",
"MissingRequirementsPleaseInstallNotice": "Please install %1$s %2$s as it is required by %3$s.",
"NoZipFileSelected": "Please select a ZIP file.",
+ "FileExceedsUploadLimit": "The selected file exceeds the upload limit of your server.",
"NumUpdatesAvailable": "%s Update(s) available",
"NoPluginSettings": "No plugin settings that can be configured",
"Origin": "Origin",
diff --git a/plugins/Marketplace/Controller.php b/plugins/Marketplace/Controller.php
index c2d9d6e6d8..aae329640c 100644
--- a/plugins/Marketplace/Controller.php
+++ b/plugins/Marketplace/Controller.php
@@ -26,6 +26,7 @@ use Piwik\Plugins\Marketplace\Input\PurchaseType;
use Piwik\Plugins\Marketplace\Input\Sort;
use Piwik\ProxyHttp;
use Piwik\SettingsPiwik;
+use Piwik\SettingsServer;
use Piwik\Url;
use Piwik\View;
use Exception;
@@ -287,6 +288,7 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
$view->isAutoUpdatePossible = SettingsPiwik::isAutoUpdatePossible();
$view->isAutoUpdateEnabled = SettingsPiwik::isAutoUpdateEnabled();
$view->isPluginUploadEnabled = CorePluginsAdmin::isPluginUploadEnabled();
+ $view->uploadLimit = SettingsServer::getPostMaxUploadSize();
$view->inReportingMenu = (bool) Common::getRequestVar('embed', 0, 'int');
return $view->render();
diff --git a/plugins/Marketplace/templates/uploadPluginDialog.twig b/plugins/Marketplace/templates/uploadPluginDialog.twig
index 7da4efddc5..ec9a9e1acf 100644
--- a/plugins/Marketplace/templates/uploadPluginDialog.twig
+++ b/plugins/Marketplace/templates/uploadPluginDialog.twig
@@ -6,7 +6,7 @@
<form enctype="multipart/form-data" method="post" id="uploadPluginForm"
action="{{ linkTo({'module':'CorePluginsAdmin', 'action':'uploadPlugin', 'nonce': installNonce}) }}">
- <input type="file" name="pluginZip">
+ <input type="file" name="pluginZip" data-max-size="{{ uploadLimit }}">
<br />
<div piwik-field uicontrol="password" name="confirmPassword" autocomplete="off"
data-title="{{ 'Login_ConfirmPasswordToContinue'|translate|e('html_attr') }}"
diff --git a/tests/PHPUnit/Unit/SettingsServerTest.php b/tests/PHPUnit/Unit/SettingsServerTest.php
new file mode 100644
index 0000000000..0c74e7a921
--- /dev/null
+++ b/tests/PHPUnit/Unit/SettingsServerTest.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Matomo - free/libre analytics platform
+ *
+ * @link https://matomo.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+namespace Piwik\Tests\Unit;
+
+use Piwik\SettingsServer;
+
+/**
+ * @group Core
+ * @group SettingsServer
+ */
+class SettingsServerTest extends \PHPUnit\Framework\TestCase
+{
+ /**
+ * Dataprovider for testGetMegaBytesFromShorthandByte
+ */
+ public function getShorthandByteTestData()
+ {
+ return [
+ ['8M', 8],
+ ['10 m', 10],
+ ['2g', 2048],
+ ['1K', 1/1024],
+ ['1048576', 1],
+ ['garbl', false],
+ ['17sdfsdf', false],
+ ];
+ }
+
+ /**
+ * @dataProvider getShorthandByteTestData
+ */
+ public function testGetMegaBytesFromShorthandByte($data, $expected)
+ {
+ $class = new \ReflectionClass(SettingsServer::class);
+ $method = $class->getMethod('getMegaBytesFromShorthandByte');
+ $method->setAccessible(true);
+ $output = $method->invoke($class, $data);
+
+ $this->assertEquals($expected, $output);
+ }
+} \ No newline at end of file