Skip to content

Commit 65d5b31

Browse files
authored
Fix invalid state events corrupting room objects (#5078)
* Fix invalid room name/canonical alias corrupting room objects Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Add test Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
1 parent 2f72f9e commit 65d5b31

File tree

2 files changed

+57
-18
lines changed

2 files changed

+57
-18
lines changed

spec/unit/models/room.spec.ts

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
import { Direction, type MatrixClient, MatrixEvent, Room } from "../../../src";
17+
import { Direction, EventType, type MatrixClient, MatrixEvent, Room } from "../../../src";
1818
import type { MockedObject } from "jest-mock";
1919

2020
const CREATOR_USER_ID = "@creator:example.org";
@@ -185,4 +185,48 @@ describe("Room", () => {
185185
expectRedacted(messageEvents, room, false);
186186
});
187187
});
188+
189+
it("should ignore invalid m.room.name events", async () => {
190+
const mockClient = createMockClient();
191+
const room = new Room("!room:example.org", mockClient, CREATOR_USER_ID);
192+
const invalidNameEvent = new MatrixEvent({
193+
type: EventType.RoomName,
194+
content: {
195+
name: { invalid: 123 },
196+
},
197+
state_key: "",
198+
event_id: "$123",
199+
room_id: room.roomId,
200+
sender: CREATOR_USER_ID,
201+
});
202+
203+
// Set up the room
204+
room.currentState.setStateEvents([invalidNameEvent]);
205+
room.recalculate();
206+
207+
expect(room.name).toEqual("Empty room");
208+
});
209+
210+
describe("getAltAliases()", () => {
211+
it("should ignore invalid events", async () => {
212+
const mockClient = createMockClient();
213+
const room = new Room("!room:example.org", mockClient, CREATOR_USER_ID);
214+
const invalidAliasEvent = new MatrixEvent({
215+
type: EventType.RoomCanonicalAlias,
216+
content: {
217+
alt_aliases: [123, "#foo:bar"],
218+
},
219+
state_key: "",
220+
event_id: "$123",
221+
room_id: room.roomId,
222+
sender: CREATOR_USER_ID,
223+
});
224+
225+
// Set up the room
226+
room.currentState.setStateEvents([invalidAliasEvent]);
227+
room.recalculate();
228+
229+
expect(room.getAltAliases()).toEqual(["#foo:bar"]);
230+
});
231+
});
188232
});

src/models/room.ts

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1783,12 +1783,11 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
17831783
allowDefault = true,
17841784
useAuthentication: boolean = false,
17851785
): string | null {
1786-
const roomAvatarEvent = this.currentState.getStateEvents(EventType.RoomAvatar, "");
1787-
if (!roomAvatarEvent && !allowDefault) {
1786+
const mainUrl = this.getMxcAvatarUrl();
1787+
if (!mainUrl && !allowDefault) {
17881788
return null;
17891789
}
17901790

1791-
const mainUrl = roomAvatarEvent ? roomAvatarEvent.getContent().url : null;
17921791
if (mainUrl) {
17931792
return getHttpUriForMxc(
17941793
baseUrl,
@@ -1810,7 +1809,8 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
18101809
* @returns the mxc avatar url or falsy
18111810
*/
18121811
public getMxcAvatarUrl(): string | null {
1813-
return this.currentState.getStateEvents(EventType.RoomAvatar, "")?.getContent()?.url || null;
1812+
const url = this.currentState.getStateEvents(EventType.RoomAvatar, "")?.getContent().url;
1813+
return typeof url === "string" ? url : null;
18141814
}
18151815

18161816
/**
@@ -1820,21 +1820,18 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
18201820
* @returns The room's canonical alias, or null if there is none
18211821
*/
18221822
public getCanonicalAlias(): string | null {
1823-
const canonicalAlias = this.currentState.getStateEvents(EventType.RoomCanonicalAlias, "");
1824-
if (canonicalAlias) {
1825-
return canonicalAlias.getContent().alias || null;
1826-
}
1827-
return null;
1823+
const canonicalAlias = this.currentState.getStateEvents(EventType.RoomCanonicalAlias, "")?.getContent().alias;
1824+
return typeof canonicalAlias === "string" ? canonicalAlias : null;
18281825
}
18291826

18301827
/**
18311828
* Get this room's alternative aliases
18321829
* @returns The room's alternative aliases, or an empty array
18331830
*/
18341831
public getAltAliases(): string[] {
1835-
const canonicalAlias = this.currentState.getStateEvents(EventType.RoomCanonicalAlias, "");
1836-
if (canonicalAlias) {
1837-
return canonicalAlias.getContent().alt_aliases || [];
1832+
const altAliases = this.currentState.getStateEvents(EventType.RoomCanonicalAlias, "")?.getContent().alt_aliases;
1833+
if (Array.isArray(altAliases)) {
1834+
return altAliases.filter((alias) => typeof alias === "string");
18381835
}
18391836
return [];
18401837
}
@@ -3640,13 +3637,11 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
36403637
*/
36413638
private calculateRoomName(userId: string, ignoreRoomNameEvent = false): string {
36423639
if (!ignoreRoomNameEvent) {
3643-
// check for an alias, if any. for now, assume first alias is the
3644-
// official one.
3645-
const mRoomName = this.currentState.getStateEvents(EventType.RoomName, "");
3646-
if (mRoomName?.getContent().name) {
3640+
const name = this.currentState.getStateEvents(EventType.RoomName, "")?.getContent().name;
3641+
if (typeof name === "string") {
36473642
return this.roomNameGenerator({
36483643
type: RoomNameType.Actual,
3649-
name: mRoomName.getContent().name,
3644+
name,
36503645
});
36513646
}
36523647
}

0 commit comments

Comments
 (0)