From af720cdab95ec0aae64ef1c190c2decbd30cab16 Mon Sep 17 00:00:00 2001 From: SpiritCroc Date: Thu, 23 Feb 2023 19:44:03 +0100 Subject: [PATCH] [rich replies] matrix-sdk: Ensure correct room for events loaded by chunks If somebody links an invalid eventId in a room, which however is valid in a different room, this can mess up our timelines badly. This can be reproduced by replying to an event in a room, then forward the reply to a different room with a client that also forwards the replied-to information (such as FluffyChat). Then click on the rich reply to open the eventId. Previously, Android could find the event from the other room and thus replace the correct timeline with the wrong one. Compare e.g. https://matrix.to/#/!bfebJVBOZMnORmkVdO:matrix.org/$wUyRiMQEjaWOpJ-XpdBJzuXkh95N7bce2pVT4IMXW50?via=schildi.chat&via=matrix.org&via=envs.net linking to an event that exists here https://matrix.to/#/!SDwMepdfgrmExhyxYZ:schildi.chat/$MO2G4MZZ1zg0Ymc9gTfekIyw7QFkNn4OvYQKK1PAGlE Change-Id: I4dcee94353d954fb6ed57c3970686a620b831c6f --- .../sdk/internal/database/helper/ThreadEventsHelper.kt | 2 +- .../sdk/internal/database/query/ChunkEntityQueries.kt | 7 ++++--- .../android/sdk/internal/database/query/ReadQueries.kt | 6 +++--- .../session/room/timeline/FetchTokenAndPaginateTask.kt | 2 +- .../internal/session/room/timeline/LoadTimelineStrategy.kt | 2 +- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadEventsHelper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadEventsHelper.kt index 7999a2ea14..a100741452 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadEventsHelper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadEventsHelper.kt @@ -297,7 +297,7 @@ internal fun updateThreadNotifications(roomId: String, realm: Realm, currentUser val readReceipt = findMyReadReceipt(realm, roomId, currentUserId, threadId = rootThreadEventId) ?: return val readReceiptChunk = ChunkEntity - .findIncludingEvent(realm, readReceipt) ?: return + .findIncludingEvent(realm, roomId, readReceipt) ?: return val readReceiptChunkThreadEvents = readReceiptChunk .timelineEvents diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ChunkEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ChunkEntityQueries.kt index 1e5d96b496..08c8bcf86e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ChunkEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ChunkEntityQueries.kt @@ -72,15 +72,16 @@ internal fun ChunkEntity.Companion.findEventInThreadChunk(realm: Realm, roomId: .findFirst() } -internal fun ChunkEntity.Companion.findAllIncludingEvents(realm: Realm, eventIds: List): RealmResults { +internal fun ChunkEntity.Companion.findAllIncludingEvents(realm: Realm, roomId: String, eventIds: List): RealmResults { return realm.where() + .equalTo(ChunkEntityFields.ROOM.ROOM_ID, roomId) .`in`(ChunkEntityFields.TIMELINE_EVENTS.EVENT_ID, eventIds.toTypedArray()) .isNull(ChunkEntityFields.ROOT_THREAD_EVENT_ID) .findAll() } -internal fun ChunkEntity.Companion.findIncludingEvent(realm: Realm, eventId: String): ChunkEntity? { - return findAllIncludingEvents(realm, listOf(eventId)).firstOrNull() +internal fun ChunkEntity.Companion.findIncludingEvent(realm: Realm, roomId: String, eventId: String): ChunkEntity? { + return findAllIncludingEvents(realm, roomId, listOf(eventId)).firstOrNull() } internal fun ChunkEntity.Companion.create( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadQueries.kt index c982ac8833..b0cb355051 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadQueries.kt @@ -114,11 +114,11 @@ private fun hasReadMissingEvent(realm: Realm, userId: String, eventId: String, threadId: String? = ReadService.THREAD_ID_MAIN): Boolean { - return realm.doesEventExistInChunkHistory(eventId) && realm.hasReadReceiptInLatestChunk(latestChunkEntity, roomId, userId, threadId) + return realm.doesEventExistInChunkHistory(roomId, eventId) && realm.hasReadReceiptInLatestChunk(latestChunkEntity, roomId, userId, threadId) } -private fun Realm.doesEventExistInChunkHistory(eventId: String): Boolean { - return ChunkEntity.findIncludingEvent(this, eventId) != null +private fun Realm.doesEventExistInChunkHistory(roomId: String, eventId: String): Boolean { + return ChunkEntity.findIncludingEvent(this, roomId, eventId) != null } private fun Realm.hasReadReceiptInLatestChunk(latestChunkEntity: ChunkEntity, roomId: String, userId: String, threadId: String?): Boolean { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/FetchTokenAndPaginateTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/FetchTokenAndPaginateTask.kt index 9d8d8ecbf1..b73dd8160b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/FetchTokenAndPaginateTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/FetchTokenAndPaginateTask.kt @@ -59,7 +59,7 @@ internal class DefaultFetchTokenAndPaginateTask @Inject constructor( ?: throw IllegalStateException("No token found") monarchy.awaitTransaction { realm -> - val chunkToUpdate = ChunkEntity.findIncludingEvent(realm, params.lastKnownEventId) + val chunkToUpdate = ChunkEntity.findIncludingEvent(realm, params.roomId, params.lastKnownEventId) if (params.direction == PaginationDirection.FORWARDS) { chunkToUpdate?.nextToken = fromToken } else { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadTimelineStrategy.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadTimelineStrategy.kt index 47b6c49960..ce7362ab5b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadTimelineStrategy.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadTimelineStrategy.kt @@ -316,7 +316,7 @@ internal class LoadTimelineStrategy constructor( .findAll() } is Mode.Permalink -> { - ChunkEntity.findAllIncludingEvents(realm, listOf(mode.originEventId)) + ChunkEntity.findAllIncludingEvents(realm, roomId, listOf(mode.originEventId)) } is Mode.Thread -> { recreateThreadChunkEntity(realm, mode.rootThreadEventId)