From 5536ddba754fcdd65f8286c75829bf7860a393a5 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Fri, 8 Mar 2019 15:05:32 +0000 Subject: [PATCH 1/6] Make `prev_state` field optional The `prev_state` field on events is not specced and so synapse shouldn't explode if an event is missing the field. Fixes #4787 --- synapse/events/__init__.py | 1 - synapse/storage/events.py | 15 --------------- 2 files changed, 16 deletions(-) diff --git a/synapse/events/__init__.py b/synapse/events/__init__.py index bd130f881..fafa13518 100644 --- a/synapse/events/__init__.py +++ b/synapse/events/__init__.py @@ -141,7 +141,6 @@ class EventBase(object): origin = _event_dict_property("origin") origin_server_ts = _event_dict_property("origin_server_ts") prev_events = _event_dict_property("prev_events") - prev_state = _event_dict_property("prev_state") redacts = _event_dict_property("redacts") room_id = _event_dict_property("room_id") sender = _event_dict_property("sender") diff --git a/synapse/storage/events.py b/synapse/storage/events.py index 990a5eaaa..428300ea0 100644 --- a/synapse/storage/events.py +++ b/synapse/storage/events.py @@ -1407,21 +1407,6 @@ class EventsStore(StateGroupWorkerStore, EventFederationStore, EventsWorkerStore values=state_values, ) - self._simple_insert_many_txn( - txn, - table="event_edges", - values=[ - { - "event_id": event.event_id, - "prev_event_id": prev_id, - "room_id": event.room_id, - "is_state": True, - } - for event, _ in state_events_and_contexts - for prev_id, _ in event.prev_state - ], - ) - # Prefill the event cache self._add_to_cache(txn, events_and_contexts) From cac4723afe9d805b5d2906665fafffaef5d3e1a9 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Fri, 8 Mar 2019 15:08:34 +0000 Subject: [PATCH 2/6] Newsfile --- changelog.d/4837.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/4837.bugfix diff --git a/changelog.d/4837.bugfix b/changelog.d/4837.bugfix new file mode 100644 index 000000000..989aeb82b --- /dev/null +++ b/changelog.d/4837.bugfix @@ -0,0 +1 @@ +Fix bug where synapse expected an un-specced `prev_state` field on state events. From d6e0be92fe01e695e06f52327736b1a2b4ab2265 Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Fri, 8 Mar 2019 15:49:38 +0000 Subject: [PATCH 3/6] Disable captcha registration by default in tests --- tests/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/utils.py b/tests/utils.py index e4c42f9fa..9c8dc9dbc 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -115,6 +115,7 @@ def default_config(name): config.signing_key = [MockKey()] config.event_cache_size = 1 config.enable_registration = True + config.enable_registration_captcha = False config.macaroon_secret_key = "not even a little secret" config.expire_access_token = False config.server_name = name From fe6c12e6cdbc2b34e93f6211c51e1eab33ae00c8 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Fri, 8 Mar 2019 16:38:23 +0000 Subject: [PATCH 4/6] Add comment to schema --- synapse/storage/schema/full_schemas/11/event_edges.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/synapse/storage/schema/full_schemas/11/event_edges.sql b/synapse/storage/schema/full_schemas/11/event_edges.sql index 52eec8835..bccd1c6f7 100644 --- a/synapse/storage/schema/full_schemas/11/event_edges.sql +++ b/synapse/storage/schema/full_schemas/11/event_edges.sql @@ -37,6 +37,8 @@ CREATE TABLE IF NOT EXISTS event_edges( event_id TEXT NOT NULL, prev_event_id TEXT NOT NULL, room_id TEXT NOT NULL, + -- We no longer insert prev_state into this table, so all new rows will have + -- is_state as false. is_state BOOL NOT NULL, UNIQUE (event_id, prev_event_id, room_id, is_state) ); From 50924ee34ad7d99a6f617cdf413946e6cc85cb2b Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 8 Mar 2019 16:49:16 +0000 Subject: [PATCH 5/6] Add changelog --- changelog.d/4839.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/4839.misc diff --git a/changelog.d/4839.misc b/changelog.d/4839.misc new file mode 100644 index 000000000..7c6868051 --- /dev/null +++ b/changelog.d/4839.misc @@ -0,0 +1 @@ +Disable captcha registration by default in unit tests. \ No newline at end of file From 2326e00bc43d61e18a5ba49e22d00da0b04c3693 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 11 Mar 2019 10:53:45 +0100 Subject: [PATCH 6/6] fix incorrect encoding of filenames with spaces in (#2090) fixes https://github.com/vector-im/riot-web/issues/3155 --- changelog.d/2090.bugfix | 1 + synapse/rest/media/v1/_base.py | 54 ++++++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 changelog.d/2090.bugfix diff --git a/changelog.d/2090.bugfix b/changelog.d/2090.bugfix new file mode 100644 index 000000000..de2d22fcb --- /dev/null +++ b/changelog.d/2090.bugfix @@ -0,0 +1 @@ +Fix a bug where media with spaces in the name would get a corrupted name. diff --git a/synapse/rest/media/v1/_base.py b/synapse/rest/media/v1/_base.py index fece1ef0b..953d89bd8 100644 --- a/synapse/rest/media/v1/_base.py +++ b/synapse/rest/media/v1/_base.py @@ -100,10 +100,29 @@ def add_file_headers(request, media_type, file_size, upload_name): request.setHeader(b"Content-Type", media_type.encode("UTF-8")) if upload_name: - if is_ascii(upload_name): - disposition = "inline; filename=%s" % (_quote(upload_name),) + # RFC6266 section 4.1 [1] defines both `filename` and `filename*`. + # + # `filename` is defined to be a `value`, which is defined by RFC2616 + # section 3.6 [2] to be a `token` or a `quoted-string`, where a `token` + # is (essentially) a single US-ASCII word, and a `quoted-string` is a + # US-ASCII string surrounded by double-quotes, using backslash as an + # escape charater. Note that %-encoding is *not* permitted. + # + # `filename*` is defined to be an `ext-value`, which is defined in + # RFC5987 section 3.2.1 [3] to be `charset "'" [ language ] "'" value-chars`, + # where `value-chars` is essentially a %-encoded string in the given charset. + # + # [1]: https://tools.ietf.org/html/rfc6266#section-4.1 + # [2]: https://tools.ietf.org/html/rfc2616#section-3.6 + # [3]: https://tools.ietf.org/html/rfc5987#section-3.2.1 + + # We avoid the quoted-string version of `filename`, because (a) synapse didn't + # correctly interpret those as of 0.99.2 and (b) they are a bit of a pain and we + # may as well just do the filename* version. + if _can_encode_filename_as_token(upload_name): + disposition = 'inline; filename=%s' % (upload_name, ) else: - disposition = "inline; filename*=utf-8''%s" % (_quote(upload_name),) + disposition = "inline; filename*=utf-8''%s" % (_quote(upload_name), ) request.setHeader(b"Content-Disposition", disposition.encode('ascii')) @@ -116,6 +135,35 @@ def add_file_headers(request, media_type, file_size, upload_name): request.setHeader(b"Content-Length", b"%d" % (file_size,)) +# separators as defined in RFC2616. SP and HT are handled separately. +# see _can_encode_filename_as_token. +_FILENAME_SEPARATOR_CHARS = set(( + "(", ")", "<", ">", "@", ",", ";", ":", "\\", '"', + "/", "[", "]", "?", "=", "{", "}", +)) + + +def _can_encode_filename_as_token(x): + for c in x: + # from RFC2616: + # + # token = 1* + # + # separators = "(" | ")" | "<" | ">" | "@" + # | "," | ";" | ":" | "\" | <"> + # | "/" | "[" | "]" | "?" | "=" + # | "{" | "}" | SP | HT + # + # CHAR = + # + # CTL = + # + if ord(c) >= 127 or ord(c) <= 32 or c in _FILENAME_SEPARATOR_CHARS: + return False + return True + + @defer.inlineCallbacks def respond_with_responder(request, responder, media_type, file_size, upload_name=None): """Responds to the request with given responder. If responder is None then