summary refs log tree commit diff
diff options
context:
space:
mode:
authorErik Johnston <erik@matrix.org>2014-12-11 15:56:01 +0000
committerErik Johnston <erik@matrix.org>2014-12-11 15:56:06 +0000
commit0b0436923819a0252a7a2a6f70a1f929b45b9114 (patch)
treee4b6286969345858b37049a5d82777200023d844
parentFix prev_content (diff)
downloadsynapse-0b0436923819a0252a7a2a6f70a1f929b45b9114.tar.xz
Fix public room joining by making sure replaces_state never points to itself.
-rw-r--r--synapse/handlers/federation.py14
-rw-r--r--synapse/state.py3
-rw-r--r--synapse/storage/_base.py6
3 files changed, 13 insertions, 10 deletions
diff --git a/synapse/handlers/federation.py b/synapse/handlers/federation.py
index 2201cd977e..17779475b8 100644
--- a/synapse/handlers/federation.py
+++ b/synapse/handlers/federation.py
@@ -349,7 +349,7 @@ class FederationHandler(BaseHandler):
         handled_events = set()
 
         try:
-            builder.event_id = self.event_factory.create_event_id()
+            builder.event_id = self.event_builder_factory.create_event_id()
             builder.origin = self.hs.hostname
             builder.content = content
 
@@ -593,13 +593,13 @@ class FederationHandler(BaseHandler):
             }
 
             event = yield self.store.get_event(event_id)
-            if hasattr(event, "state_key"):
+            if event and event.is_state():
                 # Get previous state
-                if hasattr(event, "replaces_state") and event.replaces_state:
-                    prev_event = yield self.store.get_event(
-                        event.replaces_state
-                    )
-                    results[(event.type, event.state_key)] = prev_event
+                if "replaces_state" in event.unsigned:
+                    prev_id = event.unsigned["replaces_state"]
+                    if prev_id != event.event_id:
+                        prev_event = yield self.store.get_event(prev_id)
+                        results[(event.type, event.state_key)] = prev_event
                 else:
                     del results[(event.type, event.state_key)]
 
diff --git a/synapse/state.py b/synapse/state.py
index 5bfa73fb46..f9ab5faf9e 100644
--- a/synapse/state.py
+++ b/synapse/state.py
@@ -159,7 +159,8 @@ class StateHandler(object):
                 key = (event.type, event.state_key)
                 if key in context.current_state:
                     replaces = context.current_state[key]
-                    event.unsigned["replaces_state"] = replaces.event_id
+                    if replaces.event_id != event.event_id:  # Paranoia check
+                        event.unsigned["replaces_state"] = replaces.event_id
 
             defer.returnValue([])
 
diff --git a/synapse/storage/_base.py b/synapse/storage/_base.py
index e9cf73a8e2..b6f8817b62 100644
--- a/synapse/storage/_base.py
+++ b/synapse/storage/_base.py
@@ -451,7 +451,8 @@ class SQLBaseStore(object):
 
         return events
 
-    def _get_event_txn(self, txn, event_id, check_redacted=True):
+    def _get_event_txn(self, txn, event_id, check_redacted=True,
+                       get_prev_content=True):
         sql = (
             "SELECT json, r.event_id FROM event_json as e "
             "LEFT JOIN redactions as r ON e.event_id = r.redacts "
@@ -487,10 +488,11 @@ class SQLBaseStore(object):
             if because:
                 ev.unsigned["redacted_because"] = because
 
-        if "replaces_state" in ev.unsigned:
+        if get_prev_content and "replaces_state" in ev.unsigned:
             ev.unsigned["prev_content"] = self._get_event_txn(
                 txn,
                 ev.unsigned["replaces_state"],
+                get_prev_content=False,
             ).get_dict()["content"]
 
         return ev