Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Escape keys when flattening dicts.
Browse files Browse the repository at this point in the history
  • Loading branch information
clokep committed Feb 7, 2023
1 parent 4dd2b61 commit 2b69fe7
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 1 deletion.
1 change: 1 addition & 0 deletions changelog.d/15004.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Implement [MSC3873](https://github.com/matrix-org/matrix-spec-proposals/pull/3873) to unambiguate push rule keys with dots in them.
2 changes: 1 addition & 1 deletion rust/src/push/base_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ pub const BASE_APPEND_OVERRIDE_RULES: &[PushRule] = &[
priority_class: 5,
conditions: Cow::Borrowed(&[Condition::Known(KnownCondition::EventMatch(
EventMatchCondition {
key: Cow::Borrowed("content.m.relates_to.rel_type"),
key: Cow::Borrowed("content.m\\.relates_to.rel_type"),
pattern: Some(Cow::Borrowed("m.replace")),
pattern_type: None,
},
Expand Down
5 changes: 5 additions & 0 deletions synapse/push/bulk_push_rule_evaluator.py
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,11 @@ def _flatten_dict(
if result is None:
result = {}
for key, value in d.items():
# Escape periods in the key with a backslash (and backslashes with an
# extra backslash). This is since a period is used as a separator between
# nested fields.
key = key.replace("\\", "\\\\").replace(".", "\\.")

if isinstance(value, str):
result[".".join(prefix + [key])] = value.lower()
elif isinstance(value, Mapping):
Expand Down
4 changes: 4 additions & 0 deletions tests/push/test_push_rule_evaluator.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ def test_nested(self) -> None:
input = {"foo": {"bar": "abc"}}
self.assertEqual({"foo.bar": "abc"}, _flatten_dict(input))

# If a field has a dot in it, escape it.
input = {"m.foo": {"b\\ar": "abc"}}
self.assertEqual({"m\\.foo.b\\\\ar": "abc"}, _flatten_dict(input))

def test_non_string(self) -> None:
"""Non-string items are dropped."""
input: Dict[str, Any] = {
Expand Down

0 comments on commit 2b69fe7

Please sign in to comment.