Skip to content

Commit 2706873

Browse files
committed
Merge branch 'master' into develop
2 parents e551b92 + 4a9006a commit 2706873

File tree

4 files changed

+37
-15
lines changed

4 files changed

+37
-15
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
Changes in [38.2.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v38.2.0) (2025-09-16)
2+
==================================================================================================
3+
Fix [CVE-2025-59160](https://www.cve.org/CVERecord?id=CVE-2025-59160) / [GHSA-mp7c-m3rh-r56v](https://github.com/matrix-org/matrix-js-sdk/security/advisories/GHSA-mp7c-m3rh-r56v)
4+
5+
6+
17
Changes in [38.1.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v38.1.0) (2025-09-09)
28
==================================================================================================
39
## ✨ Features

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "matrix-js-sdk",
3-
"version": "38.1.0",
3+
"version": "38.2.0",
44
"description": "Matrix Client-Server SDK for Javascript",
55
"engines": {
66
"node": ">=22.0.0"

spec/unit/matrix-client.spec.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2998,6 +2998,8 @@ describe("MatrixClient", function () {
29982998
replacedByDynamicPredecessor2,
29992999
room2,
30003000
];
3001+
client.store.getRoom = (roomId: string) =>
3002+
client.store.getRooms().find((r) => r.roomId === roomId) || null;
30013003
room1.addLiveEvents(
30023004
[
30033005
roomCreateEvent(room1.roomId, replacedByCreate1.roomId),
@@ -3036,6 +3038,7 @@ describe("MatrixClient", function () {
30363038
replacedByDynamicPredecessor2,
30373039
};
30383040
}
3041+
30393042
it("Returns an empty list if there are no rooms", () => {
30403043
client.store = new StubStore();
30413044
client.store.getRooms = () => [];
@@ -3062,6 +3065,8 @@ describe("MatrixClient", function () {
30623065
const room2 = new Room("room2", client, "@daryl:alexandria.example.com");
30633066
client.store = new StubStore();
30643067
client.store.getRooms = () => [room1, replacedRoom1, replacedRoom2, room2];
3068+
client.store.getRoom = (roomId: string) =>
3069+
client.store.getRooms().find((r) => r.roomId === roomId) || null;
30653070
room1.addLiveEvents([roomCreateEvent(room1.roomId, replacedRoom1.roomId)], { addToState: true });
30663071
room2.addLiveEvents([roomCreateEvent(room2.roomId, replacedRoom2.roomId)], { addToState: true });
30673072
replacedRoom1.addLiveEvents([tombstoneEvent(room1.roomId, replacedRoom1.roomId)], { addToState: true });
@@ -3127,6 +3132,24 @@ describe("MatrixClient", function () {
31273132
expect(rooms).toContain(room1);
31283133
expect(rooms).toContain(room2);
31293134
});
3135+
3136+
it("should ignore room replacements which are not reciprocated by the predecessor", () => {
3137+
const room1 = new Room("room1", client, "@carol:alexandria.example.com");
3138+
// Room 2 claims to replace room 1 but room 1 does not agree
3139+
const room2 = new Room("replacedRoom1", client, "@daryl:alexandria.example.com");
3140+
3141+
client.store = new StubStore();
3142+
client.store.getRooms = () => [room1, room2];
3143+
client.store.getRoom = (roomId: string) =>
3144+
client.store.getRooms().find((r) => r.roomId === roomId) || null;
3145+
3146+
room2.addLiveEvents([roomCreateEvent(room2.roomId, room1.roomId)], { addToState: true });
3147+
3148+
// When we ask for the visible rooms
3149+
const rooms = client.getVisibleRooms();
3150+
expect(rooms).toContain(room1);
3151+
expect(rooms).toContain(room2);
3152+
});
31303153
});
31313154

31323155
describe("getRoomUpgradeHistory", () => {

src/client.ts

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2141,21 +2141,14 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
21412141
public getVisibleRooms(msc3946ProcessDynamicPredecessor = false): Room[] {
21422142
const allRooms = this.store.getRooms();
21432143

2144-
const replacedRooms = new Set();
2145-
for (const r of allRooms) {
2146-
const predecessor = r.findPredecessor(msc3946ProcessDynamicPredecessor)?.roomId;
2147-
if (predecessor) {
2148-
replacedRooms.add(predecessor);
2144+
const visibleRooms = new Set(allRooms);
2145+
for (const room of visibleRooms) {
2146+
const predecessors = this.findPredecessorRooms(room, true, msc3946ProcessDynamicPredecessor);
2147+
for (const predecessor of predecessors) {
2148+
visibleRooms.delete(predecessor);
21492149
}
21502150
}
2151-
2152-
return allRooms.filter((r) => {
2153-
const tombstone = r.currentState.getStateEvents(EventType.RoomTombstone, "");
2154-
if (tombstone && replacedRooms.has(r.roomId)) {
2155-
return false;
2156-
}
2157-
return true;
2158-
});
2151+
return Array.from(visibleRooms);
21592152
}
21602153

21612154
/**
@@ -3852,7 +3845,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
38523845
roomId: string,
38533846
includeFuture = true,
38543847
): Promise<{ [roomId: string]: Error | MatrixError | null }> {
3855-
const upgradeHistory = this.getRoomUpgradeHistory(roomId);
3848+
const upgradeHistory = this.getRoomUpgradeHistory(roomId, true);
38563849

38573850
let eligibleToLeave = upgradeHistory;
38583851
if (!includeFuture) {

0 commit comments

Comments
 (0)