diff --git a/changelog.d/6642.misc b/changelog.d/6642.misc
new file mode 100644
index 0000000000..a480bbd134
--- /dev/null
+++ b/changelog.d/6642.misc
@@ -0,0 +1 @@
+Fix errors when frozen_dicts are enabled.
diff --git a/synapse/crypto/event_signing.py b/synapse/crypto/event_signing.py
index ccaa8a9920..e65bd61d97 100644
--- a/synapse/crypto/event_signing.py
+++ b/synapse/crypto/event_signing.py
@@ -14,7 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
+import collections.abc
import hashlib
import logging
@@ -40,8 +40,11 @@ def check_event_content_hash(event, hash_algorithm=hashlib.sha256):
# some malformed events lack a 'hashes'. Protect against it being missing
# or a weird type by basically treating it the same as an unhashed event.
hashes = event.get("hashes")
- if not isinstance(hashes, dict):
- raise SynapseError(400, "Malformed 'hashes'", Codes.UNAUTHORIZED)
+ # nb it might be a frozendict or a dict
+ if not isinstance(hashes, collections.abc.Mapping):
+ raise SynapseError(
+ 400, "Malformed 'hashes': %s" % (type(hashes),), Codes.UNAUTHORIZED
+ )
if name not in hashes:
raise SynapseError(
diff --git a/synapse/handlers/room.py b/synapse/handlers/room.py
index 4f489762fc..9cab2adbfb 100644
--- a/synapse/handlers/room.py
+++ b/synapse/handlers/room.py
@@ -16,7 +16,7 @@
# limitations under the License.
"""Contains functions for performing events on rooms."""
-import copy
+
import itertools
import logging
import math
@@ -368,13 +368,16 @@ class RoomCreationHandler(BaseHandler):
# Raise the requester's power level in the new room if necessary
current_power_level = power_levels["users"][user_id]
if current_power_level < needed_power_level:
- # Perform a deepcopy in order to not modify the original power levels in a
- # room, as its contents are preserved as the state for the old room later on
- new_power_levels = copy.deepcopy(power_levels)
- initial_state[(EventTypes.PowerLevels, "")] = new_power_levels
+ # make sure we copy the event content rather than overwriting it.
+ # note that if frozen_dicts are enabled, `power_levels` will be a frozen
+ # dict so we can't just copy.deepcopy it.
- # Assign this power level to the requester
+ new_power_levels = {k: v for k, v in power_levels.items() if k != "users"}
+ new_power_levels["users"] = {
+ k: v for k, v in power_levels.get("users", {}).items() if k != user_id
+ }
new_power_levels["users"][user_id] = needed_power_level
+ initial_state[(EventTypes.PowerLevels, "")] = new_power_levels
yield self._send_events_for_new_room(
requester,
diff --git a/synapse/handlers/room_member.py b/synapse/handlers/room_member.py
index 44c5e3239c..dbb0c3dda2 100644
--- a/synapse/handlers/room_member.py
+++ b/synapse/handlers/room_member.py
@@ -507,6 +507,8 @@ class RoomMemberHandler(object):
Returns:
Deferred
"""
+ logger.info("Transferring room state from %s to %s", old_room_id, room_id)
+
# Find all local users that were in the old room and copy over each user's state
users = yield self.store.get_users_in_room(old_room_id)
yield self.copy_user_state_on_room_upgrade(old_room_id, room_id, users)
diff --git a/synapse/storage/data_stores/main/state.py b/synapse/storage/data_stores/main/state.py
index 0dc39f139c..d07440e3ed 100644
--- a/synapse/storage/data_stores/main/state.py
+++ b/synapse/storage/data_stores/main/state.py
@@ -12,7 +12,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-
+import collections.abc
import logging
from collections import namedtuple
from typing import Iterable, Tuple
@@ -107,7 +107,7 @@ class StateGroupWorkerStore(EventsWorkerStore, SQLBaseStore):
predecessor = create_event.content.get("predecessor", None)
# Ensure the key is a dictionary
- if not isinstance(predecessor, dict):
+ if not isinstance(predecessor, collections.abc.Mapping):
return None
return predecessor
|