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
## 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

View file

@ -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,

View file

@ -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)

View file

@ -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)