Skip to content
Snippets Groups Projects
Unverified Commit 9356656e authored by Patrick Cloke's avatar Patrick Cloke Committed by GitHub
Browse files

Do not try to store invalid data in the stats table (#8226)

parent d250521c
No related branches found
No related tags found
No related merge requests found
Fix a longstanding bug where stats updates could break when unexpected profile data was included in events.
...@@ -224,14 +224,32 @@ class StatsStore(StateDeltasStore): ...@@ -224,14 +224,32 @@ class StatsStore(StateDeltasStore):
) )
async def update_room_state(self, room_id: str, fields: Dict[str, Any]) -> None: async def update_room_state(self, room_id: str, fields: Dict[str, Any]) -> None:
""" """Update the state of a room.
fields can contain the following keys with string values:
* join_rules
* history_visibility
* encryption
* name
* topic
* avatar
* canonical_alias
A is_federatable key can also be included with a boolean value.
Args: Args:
room_id room_id: The room ID to update the state of.
fields fields: The fields to update. This can include a partial list of the
above fields to only update some room information.
""" """
# Ensure that the values to update are valid, they should be strings and
# For whatever reason some of the fields may contain null bytes, which # not contain any null bytes.
# postgres isn't a fan of, so we replace those fields with null. #
# Invalid data gets overwritten with null.
#
# Note that a missing value should not be overwritten (it keeps the
# previous value).
sentinel = object()
for col in ( for col in (
"join_rules", "join_rules",
"history_visibility", "history_visibility",
...@@ -241,8 +259,8 @@ class StatsStore(StateDeltasStore): ...@@ -241,8 +259,8 @@ class StatsStore(StateDeltasStore):
"avatar", "avatar",
"canonical_alias", "canonical_alias",
): ):
field = fields.get(col) field = fields.get(col, sentinel)
if field and "\0" in field: if field is not sentinel and (not isinstance(field, str) or "\0" in field):
fields[col] = None fields[col] = None
await self.db_pool.simple_upsert( await self.db_pool.simple_upsert(
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment