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
path: root/core
diff options
context:
space:
mode:
authordizzy <diosmosis@users.noreply.github.com>2021-08-12 10:13:00 +0300
committerGitHub <noreply@github.com>2021-08-12 10:13:00 +0300
commit9873cb71e66be0f80839c76e923c3b866dd23b46 (patch)
tree3973fe06503f6099998c85e5cf435146b1b9a711 /core
parent99136cbf3183833b5d9dedb7943873fb8c3a8da5 (diff)
avoid large amounts of notifications being added to the session (#17736)
* impose limit on notification message size when logging to notifications * if in memory notification count exceeds max notification size in session, do not attempt to new ones it to the session * Detect when session was too large to read and provide warning to user. * add some tests for Notification\ManagerTest.php * add tests for relevant DbTable members * Change session data column type to allow larger session data values. * update to rc3 * trigger new build? * fix namespace * fix test namespaces * bump version correctly
Diffstat (limited to 'core')
-rw-r--r--core/Db/Schema/Mysql.php2
-rw-r--r--core/Notification/Manager.php26
-rw-r--r--core/Session.php19
-rw-r--r--core/Session/SaveHandler/DbTable.php2
-rw-r--r--core/Session/SessionAuth.php12
-rw-r--r--core/Updates/4.5.0-b1.php43
-rw-r--r--core/Version.php3
7 files changed, 95 insertions, 12 deletions
diff --git a/core/Db/Schema/Mysql.php b/core/Db/Schema/Mysql.php
index c7afaa6d87..940f694e70 100644
--- a/core/Db/Schema/Mysql.php
+++ b/core/Db/Schema/Mysql.php
@@ -275,7 +275,7 @@ class Mysql implements SchemaInterface
id VARCHAR( 191 ) NOT NULL,
modified INTEGER,
lifetime INTEGER,
- data TEXT,
+ data MEDIUMTEXT,
PRIMARY KEY ( id )
) ENGINE=$engine DEFAULT CHARSET=$charset
",
diff --git a/core/Notification/Manager.php b/core/Notification/Manager.php
index a621f27bfd..6e1924e873 100644
--- a/core/Notification/Manager.php
+++ b/core/Notification/Manager.php
@@ -18,6 +18,7 @@ use Piwik\Session\SessionNamespace;
*/
class Manager
{
+ const MAX_NOTIFICATIONS_IN_SESSION = 30;
/**
* @var SessionNamespace
*/
@@ -36,6 +37,8 @@ class Manager
* element ID. It can only contain alphanumeric characters (underscores can
* be used).
* @param Notification $notification The notification to post.
+ * @return bool true if the notification was added, false if it was ignored because there were too many
+ * pending ones.
* @api
*/
public static function notify($id, Notification $notification)
@@ -43,7 +46,7 @@ class Manager
self::checkId($id);
self::removeOldestNotificationsIfThereAreTooMany();
- self::addNotification($id, $notification);
+ return self::addNotification($id, $notification);
}
/**
@@ -103,7 +106,7 @@ class Manager
throw new \Exception('Notification ID is empty.');
}
- if (!preg_match('/^(\w)*$/', $id)) {
+ if (!preg_match('/^\w*$/', $id)) {
throw new \Exception('Invalid Notification ID given. Only word characters (AlNum + underscore) allowed.');
}
}
@@ -112,9 +115,15 @@ class Manager
{
self::saveNotificationAcrossUiRequestsIfNeeded($id, $notification);
+ if (count(self::$notifications) >= self::MAX_NOTIFICATIONS_IN_SESSION) {
+ return false;
+ }
+
// we store all kinda notifications here so in case the session is not enabled or disabled later there is still
// a chance it gets delivered to the UI during the same request.
self::$notifications[$id] = $notification;
+
+ return true;
}
private static function saveNotificationAcrossUiRequestsIfNeeded($id, Notification $notification)
@@ -133,7 +142,7 @@ class Manager
return;
}
- $maxNotificationsInSession = 30;
+ $maxNotificationsInSession = self::MAX_NOTIFICATIONS_IN_SESSION;
$session = static::getSession();
@@ -200,4 +209,15 @@ class Manager
return static::$session;
}
+
+ public static function cancelAllNotifications()
+ {
+ self::$notifications = [];
+ }
+
+ // for tests
+ public static function getPendingInMemoryNotifications()
+ {
+ return self::$notifications;
+ }
}
diff --git a/core/Session.php b/core/Session.php
index 4c09c3b6cb..641334676c 100644
--- a/core/Session.php
+++ b/core/Session.php
@@ -100,13 +100,7 @@ class Session extends Zend_Session
@ini_set('session.serialize_handler', 'php_serialize');
}
- $config = array(
- 'name' => Common::prefixTable(DbTable::TABLE_NAME),
- 'primary' => 'id',
- 'modifiedColumn' => 'modified',
- 'dataColumn' => 'data',
- 'lifetimeColumn' => 'lifetime',
- );
+ $config = self::getDbTableConfig();
$saveHandler = new DbTable($config);
if ($saveHandler) {
@@ -226,4 +220,15 @@ class Session extends Zend_Session
Common::sendHeader($headerStr);
return $headerStr;
}
+
+ public static function getDbTableConfig()
+ {
+ return array(
+ 'name' => Common::prefixTable(DbTable::TABLE_NAME),
+ 'primary' => 'id',
+ 'modifiedColumn' => 'modified',
+ 'dataColumn' => 'data',
+ 'lifetimeColumn' => 'lifetime',
+ );
+ }
}
diff --git a/core/Session/SaveHandler/DbTable.php b/core/Session/SaveHandler/DbTable.php
index 46012cc216..52bbeeb37f 100644
--- a/core/Session/SaveHandler/DbTable.php
+++ b/core/Session/SaveHandler/DbTable.php
@@ -23,6 +23,8 @@ use Zend_Session_SaveHandler_Interface;
*/
class DbTable implements Zend_Session_SaveHandler_Interface
{
+ public static $wasSessionToLargeToRead = false;
+
protected $config;
protected $maxLifetime;
diff --git a/core/Session/SessionAuth.php b/core/Session/SessionAuth.php
index 19e7e24e19..bff91c113e 100644
--- a/core/Session/SessionAuth.php
+++ b/core/Session/SessionAuth.php
@@ -13,10 +13,12 @@ use Piwik\Auth;
use Piwik\AuthResult;
use Piwik\Common;
use Piwik\Config;
+use Piwik\Container\StaticContainer;
use Piwik\Date;
use Piwik\Plugins\UsersManager\Model;
use Piwik\Plugins\UsersManager\Model as UsersModel;
use Piwik\Session;
+use Psr\Log\LoggerInterface;
/**
* Validates already authenticated sessions.
@@ -94,6 +96,8 @@ class SessionAuth implements Auth
$sessionFingerprint = new SessionFingerprint();
$userModel = $this->userModel;
+ $this->checkIfSessionFailedToRead();
+
if ($this->isExpiredSession($sessionFingerprint)) {
$sessionFingerprint->clear();
return $this->makeAuthFailure();
@@ -231,4 +235,12 @@ class SessionAuth implements Auth
$isExpired = Date::now()->getTimestampUTC() > $expirationTime;
return $isExpired;
}
+
+ private function checkIfSessionFailedToRead()
+ {
+ if (Session\SaveHandler\DbTable::$wasSessionToLargeToRead) {
+ StaticContainer::get(LoggerInterface::class)->warning(
+ "Too much data stored in the session so it could not be read properly. If you were logged out, this is why.");
+ }
+ }
}
diff --git a/core/Updates/4.5.0-b1.php b/core/Updates/4.5.0-b1.php
new file mode 100644
index 0000000000..e79ebe7107
--- /dev/null
+++ b/core/Updates/4.5.0-b1.php
@@ -0,0 +1,43 @@
+<?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\Updates;
+
+use Piwik\Updater;
+use Piwik\Updates as PiwikUpdates;
+use Piwik\Updater\Migration;
+use Piwik\Updater\Migration\Factory as MigrationFactory;
+
+class Updates_4_5_0_b1 extends PiwikUpdates
+{
+
+ /**
+ * @var MigrationFactory
+ */
+ private $migration;
+
+ public function __construct(MigrationFactory $factory)
+ {
+ $this->migration = $factory;
+ }
+
+ public function getMigrations(Updater $updater)
+ {
+ $migration1 = $this->migration->db->changeColumnType('session', 'data', 'MEDIUMTEXT');
+
+ return [
+ $migration1,
+ ];
+ }
+
+ public function doUpdate(Updater $updater)
+ {
+ $updater->executeMigrations(__FILE__, $this->getMigrations($updater));
+ }
+}
diff --git a/core/Version.php b/core/Version.php
index 8c0ebd1d8d..cd40ab0d9e 100644
--- a/core/Version.php
+++ b/core/Version.php
@@ -20,7 +20,8 @@ final class Version
* The current Matomo version.
* @var string
*/
- const VERSION = '4.4.1';
+ const VERSION = '4.5.0-b1';
+
const MAJOR_VERSION = 4;
public function isStableVersion($version)