diff --git a/src/models/room-member.ts b/src/models/room-member.ts index 01948ac16c3..b0a2ba827d8 100644 --- a/src/models/room-member.ts +++ b/src/models/room-member.ts @@ -131,7 +131,9 @@ export class RoomMember extends EventEmitter { this.disambiguate, ); - this.rawDisplayName = event.getDirectionalContent().displayname; + // not quite raw: we strip direction override chars so it can safely be inserted into + // blocks of text without breaking the text direction + this.rawDisplayName = utils.removeDirectionOverrideChars(event.getDirectionalContent().displayname); if (!this.rawDisplayName || !utils.removeHiddenChars(this.rawDisplayName)) { this.rawDisplayName = this.userId; } @@ -355,7 +357,7 @@ function calculateDisplayName( roomState: RoomState, disambiguate: boolean, ): string { - if (disambiguate) return displayName + " (" + selfUserId + ")"; + if (disambiguate) return utils.removeDirectionOverrideChars(displayName) + " (" + selfUserId + ")"; if (!displayName || displayName === selfUserId) return selfUserId; @@ -363,7 +365,18 @@ function calculateDisplayName( // after stripping it of zero width characters and padding spaces if (!utils.removeHiddenChars(displayName)) return selfUserId; - return displayName; + // We always strip the direction override characters (LRO and RLO). + // These override the text direction for all subsequent characters + // in the paragraph so if display names contained these, they'd + // need to be wrapped in something to prevent this from leaking out + // (which we can do in HTML but not text) or we'd need to add + // control characters to the string to reset any overrides (eg. + // adding PDF characters at the end). As far as we can see, + // there should be no reason these would be necessary - rtl display + // names should flip into the correct direction automatically based on + // the characters, and you can still embed rtl in ltr or vice versa + // with the embed chars or marker chars. + return utils.removeDirectionOverrideChars(displayName); } /** diff --git a/src/utils.ts b/src/utils.ts index 0a0f259e4ae..d24f1601d55 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -387,6 +387,18 @@ export function removeHiddenChars(str: string): string { return ""; } +/** + * Removes the direction override characters from a string + * @param {string} input + * @returns string with chars removed + */ +export function removeDirectionOverrideChars(str: string): string { + if (typeof str === "string") { + return str.replace(/[\u202d-\u202e]/g, ''); + } + return ""; +} + export function normalize(str: string): string { // Note: we have to match the filter with the removeHiddenChars() because the // function strips spaces and other characters (M becomes RN for example, in lowercase).