From 80d270da3842e827d5a1eb0f712bde234a520cd4 Mon Sep 17 00:00:00 2001 From: Askaholic Date: Sun, 31 Dec 2023 20:06:54 -0500 Subject: [PATCH] Strip whitespace from game title and enforce minimum length --- server/games/game.py | 7 +++- server/lobbyconnection.py | 2 ++ tests/integration_tests/test_server.py | 50 ++++++++++++++++++++++++++ tests/unit_tests/test_game.py | 6 ++++ 4 files changed, 64 insertions(+), 1 deletion(-) diff --git a/server/games/game.py b/server/games/game.py index ef91e12f8..ab8d10a9e 100644 --- a/server/games/game.py +++ b/server/games/game.py @@ -164,8 +164,13 @@ def name(self, value: str): """ Verifies that names only contain ascii characters. """ + value = value.strip() + if not value.isascii(): - raise ValueError("Name must be ascii!") + raise ValueError("Game title must be ascii!") + + if not value: + raise ValueError("Game title must not be empty!") self.set_name_unchecked(value) diff --git a/server/lobbyconnection.py b/server/lobbyconnection.py index e5b460cb4..c536c758d 100644 --- a/server/lobbyconnection.py +++ b/server/lobbyconnection.py @@ -949,6 +949,8 @@ async def command_game_host(self, message): title = message.get("title") or f"{self.player.login}'s game" if not title.isascii(): raise ClientError("Title must contain only ascii characters.") + if not title.strip(): + raise ClientError("Title must not be empty.") mod = message.get("mod") or FeaturedModType.FAF mapname = message.get("mapname") or "scmp_007" diff --git a/tests/integration_tests/test_server.py b/tests/integration_tests/test_server.py index 4fb79feb4..a1199e2d9 100644 --- a/tests/integration_tests/test_server.py +++ b/tests/integration_tests/test_server.py @@ -683,6 +683,56 @@ async def test_host_missing_fields(lobby_server): assert msg["featured_mod"] == "faf" +@fast_forward(10) +async def test_host_game_name_only_spaces(lobby_server): + player_id, session, proto = await connect_and_sign_in( + ("test", "test_password"), + lobby_server + ) + + await read_until_command(proto, "game_info") + + await proto.send_message({ + "command": "game_host", + "mod": "", + "visibility": "public", + "title": " ", + }) + + msg = await read_until_command(proto, "notice", timeout=10) + + assert msg == { + "command": "notice", + "style": "error", + "text": "Title must not be empty.", + } + + +@fast_forward(10) +async def test_host_game_name_non_ascii(lobby_server): + player_id, session, proto = await connect_and_sign_in( + ("test", "test_password"), + lobby_server + ) + + await read_until_command(proto, "game_info") + + await proto.send_message({ + "command": "game_host", + "mod": "", + "visibility": "public", + "title": "ÇÒÖL GÃMÊ" + }) + + msg = await read_until_command(proto, "notice", timeout=10) + + assert msg == { + "command": "notice", + "style": "error", + "text": "Title must contain only ascii characters." + } + + async def test_play_game_while_queueing(lobby_server): player_id, session, proto = await connect_and_sign_in( ("test", "test_password"), diff --git a/tests/unit_tests/test_game.py b/tests/unit_tests/test_game.py index 43e34106b..c8e0fca39 100644 --- a/tests/unit_tests/test_game.py +++ b/tests/unit_tests/test_game.py @@ -613,6 +613,12 @@ async def test_name_sanitization(game, players): with pytest.raises(ValueError): game.name = "Hello ⏴⏵⏶⏷⏸⏹⏺⏻♿" + with pytest.raises(ValueError): + game.name = " \n\n\t" + + with pytest.raises(ValueError): + game.name = "" + game.name = "A" * 256 assert game.name == "A" * 128