diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c80142361..907f0f7f1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## Main + +- Bug fix: Better handler malformed alias-regex given to nickhandler. A + regex-relevant character in a channel alias could cause server to not restart. +- Add `attr` keyword to `create_channel`. This allows setting attributes on + channels at creation, also from `DEFAULT_CHANNELS` definitions. + ## Evennia 1.1.0 Jan 7, 2023 diff --git a/evennia/comms/comms.py b/evennia/comms/comms.py index 9c31951a15..9a68d31d36 100644 --- a/evennia/comms/comms.py +++ b/evennia/comms/comms.py @@ -2,6 +2,8 @@ Base typeclass for in-game Channels. """ +import re + from django.contrib.contenttypes.models import ContentType from django.urls import reverse from django.utils.text import slugify @@ -476,7 +478,7 @@ class DefaultChannel(ChannelDB, metaclass=TypeclassBase): # the message-pattern allows us to type the channel on its own without # needing to use the `channel` command explicitly. - msg_nick_pattern = self.channel_msg_nick_pattern.format(alias=alias) + msg_nick_pattern = self.channel_msg_nick_pattern.format(alias=re.escape(alias)) msg_nick_replacement = self.channel_msg_nick_replacement.format(channelname=chan_key) user.nicks.add( msg_nick_pattern, diff --git a/evennia/typeclasses/attributes.py b/evennia/typeclasses/attributes.py index 709dcdc8dd..2fc7a5533e 100644 --- a/evennia/typeclasses/attributes.py +++ b/evennia/typeclasses/attributes.py @@ -15,7 +15,6 @@ from collections import defaultdict from django.conf import settings from django.db import models from django.utils.encoding import smart_str - from evennia.locks.lockhandler import LockHandler from evennia.utils.dbserialize import from_pickle, to_pickle from evennia.utils.idmapper.models import SharedMemoryModel @@ -339,10 +338,12 @@ class Attribute(IAttribute, SharedMemoryModel): db_value = PickledObjectField( "value", null=True, - help_text="The data returned when the attribute is accessed. Must be " - "written as a Python literal if editing through the admin " - "interface. Attribute values which are not Python literals " - "cannot be edited through the admin interface.", + help_text=( + "The data returned when the attribute is accessed. Must be " + "written as a Python literal if editing through the admin " + "interface. Attribute values which are not Python literals " + "cannot be edited through the admin interface." + ), ) db_strvalue = models.TextField( "strvalue", null=True, blank=True, help_text="String-specific storage for quick look-up" @@ -365,9 +366,11 @@ class Attribute(IAttribute, SharedMemoryModel): db_index=True, blank=True, null=True, - help_text="Which model of object this attribute is attached to (A " - "natural key like 'objects.objectdb'). You should not change " - "this value unless you know what you are doing.", + help_text=( + "Which model of object this attribute is attached to (A " + "natural key like 'objects.objectdb'). You should not change " + "this value unless you know what you are doing." + ), ) # subclass of Attribute (None or nick) db_attrtype = models.CharField( @@ -1734,7 +1737,13 @@ class NickHandler(AttributeHandler): nick_regex, template, _, _ = nick.value regex = self._regex_cache.get(nick_regex) if not regex: - regex = re.compile(nick_regex, re.I + re.DOTALL + re.U) + try: + regex = re.compile(nick_regex, re.I + re.DOTALL + re.U) + except re.error: + from evennia.utils import logger + + logger.log_trace("Probably nick being created with unvalidated regex mapping.") + continue self._regex_cache[nick_regex] = regex is_match, raw_string = parse_nick_template(raw_string, regex, template) diff --git a/evennia/typeclasses/tests.py b/evennia/typeclasses/tests.py index 0c777718da..a7793ad79f 100644 --- a/evennia/typeclasses/tests.py +++ b/evennia/typeclasses/tests.py @@ -4,11 +4,10 @@ Unit tests for typeclass base system """ from django.test import override_settings -from mock import patch -from parameterized import parameterized - from evennia.objects.objects import DefaultObject from evennia.utils.test_resources import BaseEvenniaTest, EvenniaTestCase +from mock import patch +from parameterized import parameterized # ------------------------------------------------------------ # Manager tests @@ -432,3 +431,17 @@ class TestNickHandler(BaseEvenniaTest): self.assertEqual(expected_replaced, actual_replaced) self.char1.nicks.clear() + + def test_nick_with_parenthesis(self): + """ + Test case where input has a special character + + """ + import re + + from evennia.typeclasses.attributes import initialize_nick_templates + + nick_regex, replacement_string = initialize_nick_templates( + re.escape("OOC["), "ooc", pattern_is_regex=True + ) + re.compile(nick_regex, re.I + re.DOTALL + re.U)