From 654562b942c9ae2c25cf4ef96205d30b56fc9999 Mon Sep 17 00:00:00 2001 From: Tim Abbott Date: Mon, 2 Oct 2017 12:56:30 -0700 Subject: [PATCH] check_message: Reject null bytes in message content. Postgres doesn't like them, we don't have an obvious way to escape them, and they tend to be sent by buggy tools where it'd be better for the user to get an error. This fixes a 500 we were getting occasionally. --- zerver/lib/actions.py | 4 ++++ zerver/tests/test_messages.py | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/zerver/lib/actions.py b/zerver/lib/actions.py index 4d136285d2..10600bd265 100644 --- a/zerver/lib/actions.py +++ b/zerver/lib/actions.py @@ -1553,6 +1553,9 @@ def check_message(sender, client, addressee, message_content = message_content_raw.rstrip() if len(message_content) == 0: raise JsonableError(_("Message must not be empty")) + if '\x00' in message_content: + raise JsonableError(_("Message must not contain null bytes")) + message_content = truncate_body(message_content) if realm is None: @@ -1652,6 +1655,7 @@ def _internal_prep_message(realm, sender, addressee, content): messages together as one database query. Call do_send_messages with a list of the return values of this method. """ + # Remove any null bytes from the content if len(content) > MAX_MESSAGE_LENGTH: content = content[0:3900] + "\n\n[message was too long and has been truncated]" diff --git a/zerver/tests/test_messages.py b/zerver/tests/test_messages.py index c085816918..62551d479a 100644 --- a/zerver/tests/test_messages.py +++ b/zerver/tests/test_messages.py @@ -1085,11 +1085,21 @@ class MessagePOSTTest(ZulipTestCase): self.assertEqual(ujson.loads(result1.content)['id'], ujson.loads(result2.content)['id']) + def test_message_with_null_bytes(self): + # type: () -> None + """ + A message with null bytes in it is handled. + """ + self.login(self.example_email("hamlet")) + post_data = {"type": "stream", "to": "Verona", "client": "test suite", + "content": u" I like null bytes \x00 in my content", "subject": "Test subject"} + result = self.client_post("/json/messages", post_data) + self.assert_json_error(result, "Message must not contain null bytes") + def test_strip_message(self): # type: () -> None """ - Sending a message longer than the maximum message length succeeds but is - truncated. + A message with mixed whitespace at the end is cleaned up. """ self.login(self.example_email("hamlet")) post_data = {"type": "stream", "to": "Verona", "client": "test suite",