Skip to content

Commit 8b32f3e

Browse files
authored
Ensure we disambiguate display names which look like MXIDs (#4540)
* Ensure we disambiguate display names which look like MXIDs Signed-off-by: Michael Telatynski <[email protected]> * Make tests clearer Signed-off-by: Michael Telatynski <[email protected]> --------- Signed-off-by: Michael Telatynski <[email protected]>
1 parent 1e9934a commit 8b32f3e

File tree

3 files changed

+58
-5
lines changed

3 files changed

+58
-5
lines changed

spec/unit/room-member.spec.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,43 @@ describe("RoomMember", function () {
486486
} as unknown as RoomState;
487487
expect(member.name).toEqual(userA); // default = user_id
488488
member.setMembershipEvent(joinEvent, roomState);
489-
expect(member.name).not.toEqual("Alíce"); // it should disambig.
489+
expect(member.name).toEqual("Alíce​ (@alice:bar)"); // it should disambig.
490+
// user_id should be there somewhere
491+
expect(member.name.indexOf(userA)).not.toEqual(-1);
492+
});
493+
494+
it("should disambiguate a user when their displayname looks like an MXID which isn't theirs", function () {
495+
const joinEvent = utils.mkMembership({
496+
event: true,
497+
mship: KnownMembership.Join,
498+
user: userA,
499+
room: roomId,
500+
name: "@clarissa\u0a83bar",
501+
});
502+
503+
const roomState = {
504+
getStateEvents: function (type: string) {
505+
if (type !== "m.room.member") {
506+
return [];
507+
}
508+
return [
509+
utils.mkMembership({
510+
event: true,
511+
mship: KnownMembership.Join,
512+
room: roomId,
513+
user: userC,
514+
name: "Alice",
515+
}),
516+
joinEvent,
517+
];
518+
},
519+
getUserIdsWithDisplayName: function (displayName: string) {
520+
return [userA, userC];
521+
},
522+
} as unknown as RoomState;
523+
expect(member.name).toEqual(userA); // default = user_id
524+
member.setMembershipEvent(joinEvent, roomState);
525+
expect(member.name).toEqual("@clarissaઃbar (@alice:bar)"); // it should disambig.
490526
// user_id should be there somewhere
491527
expect(member.name.indexOf(userA)).not.toEqual(-1);
492528
});

spec/unit/utils.spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import {
3232
MapWithDefault,
3333
globToRegexp,
3434
escapeRegExp,
35+
removeHiddenChars,
3536
} from "../../src/utils";
3637
import { logger } from "../../src/logger";
3738
import { mkMessage } from "../test-utils/test-utils";
@@ -740,4 +741,19 @@ describe("utils", function () {
740741
expect(result).toMatchInlineSnapshot(`"\\[FIT-Connect Zustelldienst \\\\\\(Testumgebung\\\\\\)\\]"`);
741742
});
742743
});
744+
745+
describe("removeHiddenChars", () => {
746+
it.each([
747+
["various width spaces U+2000 - U+200D", "\u2000\u200D", ""],
748+
["LTR and RTL marks U+200E and U+200F", "\u200E\u200F", ""],
749+
["LTR/RTL and other directional formatting marks U+202A - U+202F", "\u202A\u202F", ""],
750+
["Arabic Letter RTL mark U+061C", "\u061C", ""],
751+
["Combining characters U+0300 - U+036F", "\u3000\u036F", ""],
752+
["Zero width no-break space (BOM) U+FEFF", "\uFEFF", ""],
753+
["Blank/invisible characters (U2800, U2062-U2063)", "\u2800\u2062\u2063", ""],
754+
["Zero Width Non Joiner", "‌", ""],
755+
])("should strip invisible characters: %s", (_, input, expected) => {
756+
expect(removeHiddenChars(input)).toBe(expected);
757+
});
758+
});
743759
});

src/models/room-member.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -408,17 +408,18 @@ const LTR_RTL_PATTERN = /[\u200E\u200F\u202A-\u202F]/;
408408

409409
function shouldDisambiguate(selfUserId: string, displayName?: string, roomState?: RoomState): boolean {
410410
if (!displayName || displayName === selfUserId) return false;
411+
if (!roomState) return false;
412+
413+
const strippedDisplayName = removeHiddenChars(displayName);
411414

412415
// First check if the displayname is something we consider truthy
413416
// after stripping it of zero width characters and padding spaces
414-
if (!removeHiddenChars(displayName)) return false;
415-
416-
if (!roomState) return false;
417+
if (!strippedDisplayName) return false;
417418

418419
// Next check if the name contains something that look like a mxid
419420
// If it does, it may be someone trying to impersonate someone else
420421
// Show full mxid in this case
421-
if (MXID_PATTERN.test(displayName)) return true;
422+
if (MXID_PATTERN.test(strippedDisplayName)) return true;
422423

423424
// Also show mxid if the display name contains any LTR/RTL characters as these
424425
// make it very difficult for us to find similar *looking* display names

0 commit comments

Comments
 (0)