Add extra validation of monitor/monitored input funcs. Resolve #3312

This commit is contained in:
Griatch 2026-02-15 13:09:40 +01:00
parent 1d43bd8bbb
commit ff283072ec
3 changed files with 48 additions and 1 deletions

View file

@ -41,6 +41,7 @@
- [Fix][issue3601]: `CmdSet.add(..., allow_duplicates=True)` didn't allow duplicate cmd keys (Griatch)
- [Fix][issue3194]: Make filtering on AttributeProperties consistent across typeclasses (Griatch)
- [Fix][issue2774]: Properly support `\n` in `evennia connections` long descriptions (Griatch)
- [Fix][issue3312]: Handle all edge cases breaking `monitor/monitored` `input_funcs` (Griatch)
- [Doc][pull3801]: Move Evennia doc build system to latest Sphinx/myST
(PowershellNinja, also honorary mention to electroglyph)
- [Doc][pull3800]: Describe support for Telnet SSH in HAProxy documentation (holl0wstar)
@ -75,6 +76,7 @@
[issue3601]: https://github.com/evennia/evennia/issues/3601
[issue3194]: https://github.com/evennia/evennia/issues/3194
[issue2774]: https://github.com/evennia/evennia/issues/2774
[issue3312]: https://github.com/evennia/evennia/issues/3312
## Evennia 5.0.1

View file

@ -499,9 +499,20 @@ def monitored(session, *args, **kwargs):
"""
from evennia.scripts.monitorhandler import MONITOR_HANDLER
import pickle
def _safe_pickle(value):
try:
pickle.dumps(value, pickle.HIGHEST_PROTOCOL)
return value
except Exception:
return str(value)
obj = session.puppet
monitors = MONITOR_HANDLER.all(obj=obj)
monitors = []
for mon_obj, fieldname, idstring, persistent, monitor_kwargs in MONITOR_HANDLER.all(obj=obj):
safe_kwargs = {key: _safe_pickle(val) for key, val in monitor_kwargs.items()}
monitors.append((_safe_pickle(mon_obj), fieldname, idstring, persistent, safe_kwargs))
session.msg(monitored=(monitors, {}))

View file

@ -0,0 +1,34 @@
"""
Tests for server input functions.
"""
import pickle
import evennia
from evennia.server import inputfuncs
from evennia.utils.test_resources import BaseEvenniaTest
class TestMonitoredInputfunc(BaseEvenniaTest):
"""
Regressions for monitor/monitored inputfunc handling.
"""
def test_monitored_payload_is_pickleable(self):
"""
The monitored payload sent over AMP must not include raw Session objects.
"""
self.session.puppet = self.char1
inputfuncs.monitor(self.session, name="location")
inputfuncs.monitored(self.session)
sent_session = evennia.SESSION_HANDLER.data_out.call_args.args[0]
sent_kwargs = evennia.SESSION_HANDLER.data_out.call_args.kwargs
monitors = sent_kwargs["monitored"][0]
monitor_kwargs = monitors[0][4]
self.assertEqual(sent_session, self.session)
self.assertIn("session", monitor_kwargs)
self.assertIsInstance(monitor_kwargs["session"], str)
pickle.dumps((self.session.sessid, sent_kwargs), pickle.HIGHEST_PROTOCOL)