Abhilash Raj pushed to branch master at GNU Mailman / Mailman Core
Commits:
757e940a by Abhilash Raj at 2022-01-29T04:38:27+00:00
Fix a bug where exception in plugin initialization can cause crash.
- - - - -
4564222d by Abhilash Raj at 2022-01-29T04:38:27+00:00
Merge branch 'fix-500' into 'master'
Fix a bug where exception in plugin initialization can cause crash.
See merge request mailman/mailman!952
- - - - -
3 changed files:
- src/mailman/core/initialize.py
- src/mailman/docs/NEWS.rst
- src/mailman/plugins/tests/test_plugins.py
Changes:
=====================================
src/mailman/core/initialize.py
=====================================
@@ -130,6 +130,27 @@ def initialize_1(config_path=None):
mailman.config.config.push('extra testing config', extra_cfg)
+@public
+def run_plugin_pre_hook(config):
+ """Run the plugin pre_hooks, if one fails, disable the offending plugin."""
+ disabled_plugins = []
+ for name in config.plugins: # pragma: nocover
+ plugin = config.plugins[name]
+ if hasattr(plugin, 'pre_hook'):
+ try:
+ plugin.pre_hook()
+ except Exception: # pragma: nocover
+ log = logging.getLogger('mailman.plugins')
+ log.exception('Plugin failed to run its pre_hook: "{}". '
+ 'It will be disabled and its components '
+ "won't be loaded.".format(name))
+ disabled_plugins.append(name)
+
+ if disabled_plugins:
+ for plugin in disabled_plugins:
+ del config.plugins[plugin]
+
+
@public
def initialize_2(debug=False, propagate_logs=None, testing=False):
"""Second initialization step.
@@ -159,18 +180,7 @@ def initialize_2(debug=False, propagate_logs=None,
testing=False):
log.warning(
'The [mailman]pre_hook configuration value has been replaced '
"by the plugins infrastructure, and won't be called.")
- # Run the plugin pre_hooks, if one fails, disable the offending plugin.
- for name in config.plugins: # pragma: nocover
- plugin = config.plugins[name]
- if hasattr(plugin, 'pre_hook'):
- try:
- plugin.pre_hook()
- except Exception: # pragma: nocover
- log = logging.getLogger('mailman.plugins')
- log.exception('Plugin failed to run its pre_hook: {}'
- 'It will be disabled and its components '
- "won't be loaded.".format(name))
- del config.plugins[name]
+ run_plugin_pre_hook(config)
# Instantiate the database class, ensure that it's of the right type, and
# initialize it. Then stash the object on our configuration object.
utility_name = ('testing' if testing else 'production')
=====================================
src/mailman/docs/NEWS.rst
=====================================
@@ -31,6 +31,9 @@ Bugs fixed
contained non-ascii. This is fixed. (Closes #965 and #967)
* The REST API will now accept JSON encoded data with boolean values for
boolean attributes. (Closes #970)
+* Fix a bug where loading a plugin which raises an exception in ``pre_hook``
+ can cause Mailman to crash trying to disable that plugin. (Closes #724)
+
.. _news-3.3.5:
=====================================
src/mailman/plugins/tests/test_plugins.py
=====================================
@@ -21,6 +21,7 @@ import sys
import unittest
from contextlib import ExitStack
+from mailman.core.initialize import run_plugin_pre_hook
from mailman.interfaces.plugin import IPlugin
from mailman.plugins.initialize import initialize
from mailman.plugins.testing.layer import PluginRESTLayer
@@ -53,6 +54,16 @@ class TestablePlugin:
resource = None
+@implementer(IPlugin)
+class ExceptionRaisingPlugin:
+ def pre_hook(self):
+ raise Exception('Bad plugin')
+
+ def post_hook(self):
+ pass
+ resource = None
+
+
class TestInitializePlugins(unittest.TestCase):
layer = ConfigLayer
@@ -144,3 +155,23 @@ class TestInitializePlugins(unittest.TestCase):
initialize()
log_mock.info.assert_called_once_with(
'Plugin not enabled, or empty class path: example')
+
+ def test_plugin_disabled_with_exception(self):
+ with ExitStack() as resources:
+ system_path = resources.enter_context(TemporaryDirectory())
+ fake_plugin_config = {
+ 'path': system_path,
+ 'enabled': 'yes',
+ 'class': 'ExamplePlugin',
+ }
+ testable_plugin = ExceptionRaisingPlugin()
+ fake_mailman_config = SimpleNamespace(
+ plugin_configs=[('example', fake_plugin_config)],
+ plugins={'example': testable_plugin},
+ )
+
+ resources.enter_context(patch(
+ 'mailman.plugins.initialize.call_name',
+ return_value=testable_plugin))
+ run_plugin_pre_hook(fake_mailman_config)
+ self.assertNotIn('example', fake_mailman_config.plugins)
View it on GitLab:
https://gitlab.com/mailman/mailman/-/compare/b0dd5d62c3225fbd1db1894d3a04be9facf11e06...4564222d71a241375abfc201224ee03ef4ca0949
--
View it on GitLab:
https://gitlab.com/mailman/mailman/-/compare/b0dd5d62c3225fbd1db1894d3a04be9facf11e06...4564222d71a241375abfc201224ee03ef4ca0949
You're receiving this email because of your account on gitlab.com.
_______________________________________________
Mailman-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/mailman-checkins.python.org/
Member address: [email protected]