Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Do not try to store invalid data in the stats table (#8226)
Browse files Browse the repository at this point in the history
  • Loading branch information
clokep authored Sep 2, 2020
1 parent d250521 commit 9356656
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 8 deletions.
1 change: 1 addition & 0 deletions changelog.d/8226.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a longstanding bug where stats updates could break when unexpected profile data was included in events.
34 changes: 26 additions & 8 deletions synapse/storage/databases/main/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,14 +224,32 @@ async def get_stats_positions(self) -> int:
)

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:
room_id
fields
room_id: The room ID to update the state of.
fields: The fields to update. This can include a partial list of the
above fields to only update some room information.
"""

# For whatever reason some of the fields may contain null bytes, which
# postgres isn't a fan of, so we replace those fields with null.
# Ensure that the values to update are valid, they should be strings and
# not contain any null bytes.
#
# 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 (
"join_rules",
"history_visibility",
Expand All @@ -241,8 +259,8 @@ async def update_room_state(self, room_id: str, fields: Dict[str, Any]) -> None:
"avatar",
"canonical_alias",
):
field = fields.get(col)
if field and "\0" in field:
field = fields.get(col, sentinel)
if field is not sentinel and (not isinstance(field, str) or "\0" in field):
fields[col] = None

await self.db_pool.simple_upsert(
Expand Down

0 comments on commit 9356656

Please sign in to comment.