|
| 1 | +# MSC3873: event_match dotted keys |
| 2 | + |
| 3 | +The current specification of [`event_match`] describes the parameter |
| 4 | +`key` as |
| 5 | + |
| 6 | +> `key`: The dot-separated path of the property of the event to match, |
| 7 | +> e.g. `content.body`. |
| 8 | +
|
| 9 | +It does not, however, clarify how to handle collisions such as in |
| 10 | + |
| 11 | + { |
| 12 | + "m": { "foo": "bar" }, |
| 13 | + "m.foo": "baz" |
| 14 | + } |
| 15 | + |
| 16 | +where it is unclear which field the dot-separated path `m.foo` should |
| 17 | +match ([#648]). |
| 18 | + |
| 19 | +Previously collisions were not often a practical problem, but as dotted-field names |
| 20 | +have become more common in Matrix, e.g. `m.relates_to` or [MSC1767]-style |
| 21 | +extensible events, this ambiguity is no longer satisfactory. |
| 22 | + |
| 23 | +The ambiguity in the specification leads to incompatible implementations as |
| 24 | +evidenced by [matrix-org/matrix-js-sdk#1454]. The current proposal resolves the |
| 25 | +ambiguity by leveraging the existing solution for the same problem used by the |
| 26 | +`event_fields` of [filters]: |
| 27 | + |
| 28 | +> List of event fields to include. If this list is absent then all fields are included. |
| 29 | +> The entries may include ‘.’ characters to indicate sub-fields. So [‘content.body’] |
| 30 | +> will include the ‘body’ field of the ‘content’ object. A literal ‘.’ character |
| 31 | +> in a field name may be escaped using a ‘\’. |
| 32 | +
|
| 33 | +This ambiguity is blocking other MSCs which all attempt to create rules on fields |
| 34 | +with dots in them, such as: |
| 35 | + |
| 36 | +* [MSC3952] Intentional Mentions |
| 37 | +* [MSC3958] Suppress notifications from message edits |
| 38 | + |
| 39 | +And likely any push rule for keywords using extensible events. |
| 40 | + |
| 41 | +## Proposal |
| 42 | + |
| 43 | +The dot (`.`) character in the `key` parameter is changed to be exclusively |
| 44 | +reserved for field separators. Any literal dot in field names are to be |
| 45 | +escaped using a backslash (`\.`) and any literal backslashes are also escaped with |
| 46 | +a backslash (`\\`). A backslash before any other character has no special meaning |
| 47 | +and is left as-is, but it is recommended that implementations do not redundantly |
| 48 | +escape characters, as they may be used for escape sequences in the future. |
| 49 | + |
| 50 | +Revisiting the example from above |
| 51 | + |
| 52 | + { |
| 53 | + "m": { "foo": "bar" }, |
| 54 | + "m.foo": "baz" |
| 55 | + } |
| 56 | + |
| 57 | +this means that `"key": "m.foo"` unambiguously matches the nested `foo` |
| 58 | +field. The top-level `m.foo` field in turn can be matched through |
| 59 | +`"key": "m\.foo"`. |
| 60 | + |
| 61 | +As mentioned above, this exact solution is already employed by |
| 62 | +[filters]. Reusing it here, therefore, increases the |
| 63 | +specification’s coherence. |
| 64 | + |
| 65 | +## Potential issues |
| 66 | + |
| 67 | +This MSC provides no mechanism for backwards compatibility. [^1] This should not |
| 68 | +impact the vast majority of users since none of the default push rules (nor common |
| 69 | +custom push rules, e.g. for keywords) are dependent on dotted field names. |
| 70 | + |
| 71 | +Implementations could attempt to disambiguate the `key` by checking all possible |
| 72 | +ambiguous version this is fragile: what do you do if both ambiguous fields exist? |
| 73 | +This gets worse as additional nested objects exist: |
| 74 | + |
| 75 | +```json |
| 76 | +{ |
| 77 | + "m": { |
| 78 | + "foo": { "bar": "abc" }, |
| 79 | + "foo.bar": "def" |
| 80 | + }, |
| 81 | + "m.foo": { "bar": "ghi" }, |
| 82 | + "m.foo.bar": "jkl" |
| 83 | +} |
| 84 | +``` |
| 85 | + |
| 86 | +This may break custom push rules that users have configured, but it is asserted |
| 87 | +that those are broken anyway, as mentioned above (see [matrix-org/matrix-js-sdk#1454]). |
| 88 | + |
| 89 | +## Alternatives |
| 90 | + |
| 91 | +Alternatives to the current proposal are to use [JSON pointers] or [JSONPath]. While |
| 92 | +being more versatile than the simplistic escaping proposed here, these are |
| 93 | +unnecessary and break backwards compatibility for *all* existing `event_match` |
| 94 | +conditions. |
| 95 | + |
| 96 | +## Security considerations |
| 97 | + |
| 98 | +None. |
| 99 | + |
| 100 | +[^1]: See [a previous version]. |
| 101 | + |
| 102 | + [`event_match`]: https://spec.matrix.org/v1.3/client-server-api/#conditions-1 |
| 103 | + [MSC1767]: https://github.com/matrix-org/matrix-spec-proposals/pull/1767 |
| 104 | + [#648]: https://github.com/matrix-org/matrix-spec/issues/648 |
| 105 | + [matrix-org/matrix-js-sdk#1454]: https://github.com/matrix-org/matrix-js-sdk/issues/1454 |
| 106 | + [MSC3952]: https://github.com/matrix-org/matrix-spec-proposals/pull/3952 |
| 107 | + [MSC3958]: https://github.com/matrix-org/matrix-spec-proposals/pull/3958 |
| 108 | + [filters]: https://spec.matrix.org/v1.3/client-server-api/#post_matrixclientv3useruseridfilter |
| 109 | + [JSON pointers]: https://www.rfc-editor.org/rfc/rfc6901 |
| 110 | + [JSONPath]: https://goessner.net/articles/JsonPath/ |
| 111 | + [a previous version]: https://github.com/matrix-org/matrix-spec-proposals/blob/cd906fcb263f667a7b8e5a626cc5b55fba3b9262/proposals/3873-event-match-dotted-keys.md?rgh-link-date=2022-08-21T18%3A02%3A02Z#backwards-compatibility |
0 commit comments