Fix displayname calculation around RTL / unhomoglyth. (#2953)
This commit is contained in:
@@ -886,7 +886,10 @@ test("should disambiguate users with invisible characters", () => {
|
|||||||
b: new Map([
|
b: new Map([
|
||||||
[carolId, carol.userId],
|
[carolId, carol.userId],
|
||||||
[bobId, `Bob (${bob.userId})`],
|
[bobId, `Bob (${bob.userId})`],
|
||||||
[bobZeroWidthSpaceId, `Bob (${bobZeroWidthSpace.userId})`],
|
[
|
||||||
|
bobZeroWidthSpaceId,
|
||||||
|
`${bobZeroWidthSpace.rawDisplayName} (${bobZeroWidthSpace.userId})`,
|
||||||
|
],
|
||||||
]),
|
]),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -97,21 +97,25 @@ describe("calculateDisplayName", () => {
|
|||||||
test.for<[{ rawDisplayName?: string; userId: string }, boolean, string]>([
|
test.for<[{ rawDisplayName?: string; userId: string }, boolean, string]>([
|
||||||
[alice, false, alice.rawDisplayName],
|
[alice, false, alice.rawDisplayName],
|
||||||
[alice, true, `${alice.rawDisplayName} (${alice.userId})`],
|
[alice, true, `${alice.rawDisplayName} (${alice.userId})`],
|
||||||
[alice, false, alice.rawDisplayName],
|
// Empty strings and zero width strings that are effectively empty are resolved as userIds
|
||||||
[{ rawDisplayName: "", userId: alice.userId }, false, alice.userId],
|
[{ rawDisplayName: "", userId: alice.userId }, false, alice.userId],
|
||||||
[
|
|
||||||
{ rawDisplayName: alice.userId, userId: alice.userId },
|
|
||||||
false,
|
|
||||||
alice.userId,
|
|
||||||
],
|
|
||||||
[bobZeroWidthSpace, false, "Bob"],
|
|
||||||
[
|
[
|
||||||
{ rawDisplayName: "\u200b\u200b\u200b", userId: alice.userId },
|
{ rawDisplayName: "\u200b\u200b\u200b", userId: alice.userId },
|
||||||
false,
|
false,
|
||||||
alice.userId,
|
alice.userId,
|
||||||
],
|
],
|
||||||
[daveRTL, false, "evaD"],
|
[
|
||||||
[daveRTL, true, `evaD (${daveRTL.userId})`],
|
{ rawDisplayName: alice.userId, userId: alice.userId },
|
||||||
|
false,
|
||||||
|
alice.userId,
|
||||||
|
],
|
||||||
|
// Zero width strings are kept intact
|
||||||
|
[bobZeroWidthSpace, false, bobZeroWidthSpace.rawDisplayName],
|
||||||
|
// Directional characters are stripped.
|
||||||
|
[daveRTL, false, daveRTL.rawDisplayName.slice(1)],
|
||||||
|
[daveRTL, true, `${daveRTL.rawDisplayName.slice(1)} (${daveRTL.userId})`],
|
||||||
|
// Ensure we do NOT unhomoglyth
|
||||||
|
[{ ...alice, rawDisplayName: "alice m" }, false, "alice m"],
|
||||||
])("correctly calculates displayname", ([member, disambiguate, result]) =>
|
])("correctly calculates displayname", ([member, disambiguate, result]) =>
|
||||||
expect(calculateDisplayName(member, disambiguate)).toEqual(result),
|
expect(calculateDisplayName(member, disambiguate)).toEqual(result),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -45,7 +45,11 @@ export function shouldDisambiguate(
|
|||||||
// NOTE: We *should* have a room member for everyone.
|
// NOTE: We *should* have a room member for everyone.
|
||||||
.filter((m) => !!m)
|
.filter((m) => !!m)
|
||||||
.filter((m) => m.userId !== userId)
|
.filter((m) => m.userId !== userId)
|
||||||
.some((m) => calculateDisplayName(m, false) === strippedDisplayName)
|
.some(
|
||||||
|
(m) =>
|
||||||
|
removeHiddenChars(calculateDisplayName(m, false)) ===
|
||||||
|
strippedDisplayName,
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,9 +60,7 @@ export function calculateDisplayName(
|
|||||||
const { rawDisplayName: displayName, userId } = member;
|
const { rawDisplayName: displayName, userId } = member;
|
||||||
if (!displayName || displayName === userId) return userId;
|
if (!displayName || displayName === userId) return userId;
|
||||||
|
|
||||||
const resultDisplayname = removeDirectionOverrideChars(
|
const resultDisplayname = removeDirectionOverrideChars(displayName);
|
||||||
removeHiddenChars(displayName),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (disambiguate) return resultDisplayname + " (" + userId + ")";
|
if (disambiguate) return resultDisplayname + " (" + userId + ")";
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,6 @@ export const bobZeroWidthSpaceId = `${bobZeroWidthSpace.userId}:${bobZeroWidthSp
|
|||||||
|
|
||||||
export const daveRTLRtcMember = mockRtcMembership("@dave2:example.org", "DDDD");
|
export const daveRTLRtcMember = mockRtcMembership("@dave2:example.org", "DDDD");
|
||||||
export const daveRTL = mockMatrixRoomMember(daveRTLRtcMember, {
|
export const daveRTL = mockMatrixRoomMember(daveRTLRtcMember, {
|
||||||
rawDisplayName: "\u200fevaD",
|
rawDisplayName: "\u202eevaD",
|
||||||
});
|
});
|
||||||
export const daveRTLId = `${daveRTL.userId}:${daveRTLRtcMember.deviceId}`;
|
export const daveRTLId = `${daveRTL.userId}:${daveRTLRtcMember.deviceId}`;
|
||||||
|
|||||||
Reference in New Issue
Block a user