@@ -224,14 +224,32 @@ async def get_stats_positions(self) -> int:
224224 )
225225
226226 async def update_room_state (self , room_id : str , fields : Dict [str , Any ]) -> None :
227- """
227+ """Update the state of a room.
228+
229+ fields can contain the following keys with string values:
230+ * join_rules
231+ * history_visibility
232+ * encryption
233+ * name
234+ * topic
235+ * avatar
236+ * canonical_alias
237+
238+ A is_federatable key can also be included with a boolean value.
239+
228240 Args:
229- room_id
230- fields
241+ room_id: The room ID to update the state of.
242+ fields: The fields to update. This can include a partial list of the
243+ above fields to only update some room information.
231244 """
232-
233- # For whatever reason some of the fields may contain null bytes, which
234- # postgres isn't a fan of, so we replace those fields with null.
245+ # Ensure that the values to update are valid, they should be strings and
246+ # not contain any null bytes.
247+ #
248+ # Invalid data gets overwritten with null.
249+ #
250+ # Note that a missing value should not be overwritten (it keeps the
251+ # previous value).
252+ sentinel = object ()
235253 for col in (
236254 "join_rules" ,
237255 "history_visibility" ,
@@ -241,8 +259,8 @@ async def update_room_state(self, room_id: str, fields: Dict[str, Any]) -> None:
241259 "avatar" ,
242260 "canonical_alias" ,
243261 ):
244- field = fields .get (col )
245- if field and "\0 " in field :
262+ field = fields .get (col , sentinel )
263+ if field is not sentinel and ( not isinstance ( field , str ) or "\0 " in field ) :
246264 fields [col ] = None
247265
248266 await self .db_pool .simple_upsert (
0 commit comments