Better handle malformed regex in nickreplace

This commit is contained in:
Griatch 2023-01-15 22:30:10 +01:00
parent 8d8b56fdf3
commit 0af1bf7561
4 changed files with 44 additions and 13 deletions

View file

@ -1,5 +1,12 @@
# Changelog # 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 ## Evennia 1.1.0
Jan 7, 2023 Jan 7, 2023

View file

@ -2,6 +2,8 @@
Base typeclass for in-game Channels. Base typeclass for in-game Channels.
""" """
import re
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.urls import reverse from django.urls import reverse
from django.utils.text import slugify 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 # the message-pattern allows us to type the channel on its own without
# needing to use the `channel` command explicitly. # 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) msg_nick_replacement = self.channel_msg_nick_replacement.format(channelname=chan_key)
user.nicks.add( user.nicks.add(
msg_nick_pattern, msg_nick_pattern,

View file

@ -15,7 +15,6 @@ from collections import defaultdict
from django.conf import settings from django.conf import settings
from django.db import models from django.db import models
from django.utils.encoding import smart_str from django.utils.encoding import smart_str
from evennia.locks.lockhandler import LockHandler from evennia.locks.lockhandler import LockHandler
from evennia.utils.dbserialize import from_pickle, to_pickle from evennia.utils.dbserialize import from_pickle, to_pickle
from evennia.utils.idmapper.models import SharedMemoryModel from evennia.utils.idmapper.models import SharedMemoryModel
@ -339,10 +338,12 @@ class Attribute(IAttribute, SharedMemoryModel):
db_value = PickledObjectField( db_value = PickledObjectField(
"value", "value",
null=True, null=True,
help_text="The data returned when the attribute is accessed. Must be " help_text=(
"written as a Python literal if editing through the admin " "The data returned when the attribute is accessed. Must be "
"interface. Attribute values which are not Python literals " "written as a Python literal if editing through the admin "
"cannot be edited through the admin interface.", "interface. Attribute values which are not Python literals "
"cannot be edited through the admin interface."
),
) )
db_strvalue = models.TextField( db_strvalue = models.TextField(
"strvalue", null=True, blank=True, help_text="String-specific storage for quick look-up" "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, db_index=True,
blank=True, blank=True,
null=True, null=True,
help_text="Which model of object this attribute is attached to (A " help_text=(
"natural key like 'objects.objectdb'). You should not change " "Which model of object this attribute is attached to (A "
"this value unless you know what you are doing.", "natural key like 'objects.objectdb'). You should not change "
"this value unless you know what you are doing."
),
) )
# subclass of Attribute (None or nick) # subclass of Attribute (None or nick)
db_attrtype = models.CharField( db_attrtype = models.CharField(
@ -1734,7 +1737,13 @@ class NickHandler(AttributeHandler):
nick_regex, template, _, _ = nick.value nick_regex, template, _, _ = nick.value
regex = self._regex_cache.get(nick_regex) regex = self._regex_cache.get(nick_regex)
if not 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 self._regex_cache[nick_regex] = regex
is_match, raw_string = parse_nick_template(raw_string, regex, template) is_match, raw_string = parse_nick_template(raw_string, regex, template)

View file

@ -4,11 +4,10 @@ Unit tests for typeclass base system
""" """
from django.test import override_settings from django.test import override_settings
from mock import patch
from parameterized import parameterized
from evennia.objects.objects import DefaultObject from evennia.objects.objects import DefaultObject
from evennia.utils.test_resources import BaseEvenniaTest, EvenniaTestCase from evennia.utils.test_resources import BaseEvenniaTest, EvenniaTestCase
from mock import patch
from parameterized import parameterized
# ------------------------------------------------------------ # ------------------------------------------------------------
# Manager tests # Manager tests
@ -432,3 +431,17 @@ class TestNickHandler(BaseEvenniaTest):
self.assertEqual(expected_replaced, actual_replaced) self.assertEqual(expected_replaced, actual_replaced)
self.char1.nicks.clear() 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)