api: Prevent special characters in topics.

Special characters, including `\r`, `\n`, and more esoteric codepoints
like non-characters, can negatively affect rendering and UI behaviour.

Check for, and prevent making new messages with, characters in the
Unicode categories of `Cc` (control characters), `Cs`, (surrogates),
and `Cn` (unassigned, non-characters).

Fixes #20128.
This commit is contained in:
Shlok Patel 2021-11-06 21:18:03 +05:30 committed by Alex Vandiver
parent bf93ae1644
commit b3c58f454f
2 changed files with 36 additions and 0 deletions

View File

@ -1,3 +1,4 @@
import unicodedata
from typing import Iterable, List, Optional, Sequence, Union, cast
from django.utils.translation import gettext as _
@ -40,6 +41,10 @@ def validate_topic(topic: str) -> str:
if topic == "":
raise JsonableError(_("Topic can't be empty"))
for character in topic:
unicodeCategory = unicodedata.category(character)
if unicodeCategory in ["Cc", "Cs", "Cn"]:
raise JsonableError(_("Invalid characters in topic!"))
return topic

View File

@ -730,6 +730,37 @@ class MessagePOSTTest(ZulipTestCase):
)
self.assert_json_error(result, "Missing topic")
def test_invalid_topic(self) -> None:
"""
Sending a message with invalid 'Cc', 'Cs' and 'Cn' category of unicode characters
"""
# For 'Cc' category
self.login("hamlet")
result = self.client_post(
"/json/messages",
{
"type": "stream",
"to": "Verona",
"client": "test suite",
"topic": "Test\n\rTopic",
"content": "Test message",
},
)
self.assert_json_error(result, "Invalid characters in topic!")
# For 'Cn' category
result = self.client_post(
"/json/messages",
{
"type": "stream",
"to": "Verona",
"client": "test suite",
"topic": "Test\uFFFETopic",
"content": "Test message",
},
)
self.assert_json_error(result, "Invalid characters in topic!")
def test_invalid_message_type(self) -> None:
"""
Messages other than the type of "private" or "stream" are considered as invalid