Do not reject `/sync` requests with unrecognised filter fields (#14369)
For forward compatibility, Synapse needs to ignore fields it does not recognise instead of raising an error. Fixes #14365. Signed-off-by: Sean Quah <seanq@matrix.org>pull/14396/head
parent
233fc6e279
commit
e980982b59
|
@ -0,0 +1 @@
|
||||||
|
Fix a long-standing bug where Synapse would raise an error when encountering an unrecognised field in a `/sync` filter, instead of ignoring it for forward compatibility.
|
|
@ -43,7 +43,7 @@ if TYPE_CHECKING:
|
||||||
from synapse.server import HomeServer
|
from synapse.server import HomeServer
|
||||||
|
|
||||||
FILTER_SCHEMA = {
|
FILTER_SCHEMA = {
|
||||||
"additionalProperties": False,
|
"additionalProperties": True, # Allow new fields for forward compatibility
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"limit": {"type": "number"},
|
"limit": {"type": "number"},
|
||||||
|
@ -63,7 +63,7 @@ FILTER_SCHEMA = {
|
||||||
}
|
}
|
||||||
|
|
||||||
ROOM_FILTER_SCHEMA = {
|
ROOM_FILTER_SCHEMA = {
|
||||||
"additionalProperties": False,
|
"additionalProperties": True, # Allow new fields for forward compatibility
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"not_rooms": {"$ref": "#/definitions/room_id_array"},
|
"not_rooms": {"$ref": "#/definitions/room_id_array"},
|
||||||
|
@ -77,7 +77,7 @@ ROOM_FILTER_SCHEMA = {
|
||||||
}
|
}
|
||||||
|
|
||||||
ROOM_EVENT_FILTER_SCHEMA = {
|
ROOM_EVENT_FILTER_SCHEMA = {
|
||||||
"additionalProperties": False,
|
"additionalProperties": True, # Allow new fields for forward compatibility
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"limit": {"type": "number"},
|
"limit": {"type": "number"},
|
||||||
|
@ -143,7 +143,7 @@ USER_FILTER_SCHEMA = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"additionalProperties": False,
|
"additionalProperties": True, # Allow new fields for forward compatibility
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,19 +46,36 @@ class FilteringTestCase(unittest.HomeserverTestCase):
|
||||||
self.datastore = hs.get_datastores().main
|
self.datastore = hs.get_datastores().main
|
||||||
|
|
||||||
def test_errors_on_invalid_filters(self):
|
def test_errors_on_invalid_filters(self):
|
||||||
|
# See USER_FILTER_SCHEMA for the filter schema.
|
||||||
invalid_filters = [
|
invalid_filters = [
|
||||||
{"boom": {}},
|
# `account_data` must be a dictionary
|
||||||
{"account_data": "Hello World"},
|
{"account_data": "Hello World"},
|
||||||
|
# `event_fields` entries must not contain backslashes
|
||||||
{"event_fields": [r"\\foo"]},
|
{"event_fields": [r"\\foo"]},
|
||||||
{"room": {"timeline": {"limit": 0}, "state": {"not_bars": ["*"]}}},
|
# `event_format` must be "client" or "federation"
|
||||||
{"event_format": "other"},
|
{"event_format": "other"},
|
||||||
|
# `not_rooms` must contain valid room IDs
|
||||||
{"room": {"not_rooms": ["#foo:pik-test"]}},
|
{"room": {"not_rooms": ["#foo:pik-test"]}},
|
||||||
|
# `senders` must contain valid user IDs
|
||||||
{"presence": {"senders": ["@bar;pik.test.com"]}},
|
{"presence": {"senders": ["@bar;pik.test.com"]}},
|
||||||
]
|
]
|
||||||
for filter in invalid_filters:
|
for filter in invalid_filters:
|
||||||
with self.assertRaises(SynapseError):
|
with self.assertRaises(SynapseError):
|
||||||
self.filtering.check_valid_filter(filter)
|
self.filtering.check_valid_filter(filter)
|
||||||
|
|
||||||
|
def test_ignores_unknown_filter_fields(self):
|
||||||
|
# For forward compatibility, we must ignore unknown filter fields.
|
||||||
|
# See USER_FILTER_SCHEMA for the filter schema.
|
||||||
|
filters = [
|
||||||
|
{"org.matrix.msc9999.future_option": True},
|
||||||
|
{"presence": {"org.matrix.msc9999.future_option": True}},
|
||||||
|
{"room": {"org.matrix.msc9999.future_option": True}},
|
||||||
|
{"room": {"timeline": {"org.matrix.msc9999.future_option": True}}},
|
||||||
|
]
|
||||||
|
for filter in filters:
|
||||||
|
self.filtering.check_valid_filter(filter)
|
||||||
|
# Must not raise.
|
||||||
|
|
||||||
def test_valid_filters(self):
|
def test_valid_filters(self):
|
||||||
valid_filters = [
|
valid_filters = [
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue