Be robust if Event.type is missing (#2946)

This commit is contained in:
Benoit Marty 2021-03-02 16:14:57 +01:00
parent 32e7845c2b
commit 4e2e73637a
13 changed files with 33 additions and 24 deletions

View file

@ -11,6 +11,7 @@ Improvements 🙌:
Bugfix 🐛:
- Try to fix crash about UrlPreview (#2640)
- Be robust if Event.type is missing (#2946)
Translations 🗣:
-

View file

@ -66,7 +66,7 @@ inline fun <reified T> T.toContent(): Content {
*/
@JsonClass(generateAdapter = true)
data class Event(
@Json(name = "type") val type: String,
@Json(name = "type") val type: String? = null,
@Json(name = "event_id") val eventId: String? = null,
@Json(name = "content") val content: Content? = null,
@Json(name = "prev_content") val prevContent: Content? = null,
@ -135,7 +135,7 @@ data class Event(
* @return the event type
*/
fun getClearType(): String {
return mxDecryptionResult?.payload?.get("type")?.toString() ?: type
return mxDecryptionResult?.payload?.get("type")?.toString() ?: type ?: EventType.MISSING_TYPE
}
/**

View file

@ -20,6 +20,8 @@ package org.matrix.android.sdk.api.session.events.model
* Constants defining known event types from Matrix specifications.
*/
object EventType {
// Used when the type is missing, which should not happen
const val MISSING_TYPE = "org.matrix.android.sdk.missing_type"
const val PRESENCE = "m.presence"
const val MESSAGE = "m.room.message"

View file

@ -45,7 +45,7 @@ internal class DefaultEncryptEventTask @Inject constructor(
// don't want to wait for any query
// if (!params.crypto.isRoomEncrypted(params.roomId)) return params.event
val localEvent = params.event
if (localEvent.eventId == null) {
if (localEvent.eventId == null || localEvent.type == null) {
throw IllegalArgumentException()
}

View file

@ -58,7 +58,7 @@ internal class DefaultSendEventTask @Inject constructor(
localId,
roomId = event.roomId ?: "",
content = event.content,
eventType = event.type
eventType = event.type ?: ""
)
}
localEchoRepository.updateSendState(localId, params.event.roomId, SendState.SENT)

View file

@ -50,7 +50,7 @@ internal class DefaultSendVerificationMessageTask @Inject constructor(
localId,
roomId = event.roomId ?: "",
content = event.content,
eventType = event.type
eventType = event.type ?: ""
)
}
localEchoRepository.updateSendState(localId, event.roomId, SendState.SENT)

View file

@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.database.mapper
import com.squareup.moshi.JsonDataException
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.UnsignedData
import org.matrix.android.sdk.api.session.room.send.SendState
import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult
@ -29,8 +30,6 @@ import timber.log.Timber
internal object EventMapper {
fun map(event: Event, roomId: String): EventEntity {
val uds = if (event.unsignedData == null) null
else MoshiProvider.providesMoshi().adapter(UnsignedData::class.java).toJson(event.unsignedData)
val eventEntity = EventEntity()
// TODO change this as we shouldn't use event everywhere
eventEntity.eventId = event.eventId ?: "$$roomId-${System.currentTimeMillis()}-${event.hashCode()}"
@ -39,14 +38,16 @@ internal object EventMapper {
eventEntity.prevContent = ContentMapper.map(event.resolvedPrevContent())
eventEntity.isUseless = IsUselessResolver.isUseless(event)
eventEntity.stateKey = event.stateKey
eventEntity.type = event.type
eventEntity.type = event.type ?: EventType.MISSING_TYPE
eventEntity.sender = event.senderId
eventEntity.originServerTs = event.originServerTs
eventEntity.redacts = event.redacts
eventEntity.age = event.unsignedData?.age ?: event.originServerTs
eventEntity.unsignedData = uds
eventEntity.unsignedData = event.unsignedData?.let {
MoshiProvider.providesMoshi().adapter(UnsignedData::class.java).toJson(it)
}
eventEntity.decryptionResultJson = event.mxDecryptionResult?.let {
MoshiProvider.providesMoshi().adapter<OlmDecryptionResult>(OlmDecryptionResult::class.java).toJson(it)
MoshiProvider.providesMoshi().adapter(OlmDecryptionResult::class.java).toJson(it)
}
eventEntity.decryptionErrorReason = event.mCryptoErrorReason
eventEntity.decryptionErrorCode = event.mCryptoError?.name

View file

@ -105,12 +105,17 @@ internal class DefaultLoadRoomMembersTask @Inject constructor(
?: realm.createObject(roomId)
val now = System.currentTimeMillis()
for (roomMemberEvent in response.roomMemberEvents) {
if (roomMemberEvent.eventId == null || roomMemberEvent.stateKey == null) {
if (roomMemberEvent.eventId == null || roomMemberEvent.stateKey == null || roomMemberEvent.type == null) {
continue
}
val ageLocalTs = roomMemberEvent.unsignedData?.age?.let { now - it }
val eventEntity = roomMemberEvent.toEntity(roomId, SendState.SYNCED, ageLocalTs).copyToRealmOrIgnore(realm, EventInsertType.PAGINATION)
CurrentStateEventEntity.getOrCreate(realm, roomId, roomMemberEvent.stateKey, roomMemberEvent.type).apply {
CurrentStateEventEntity.getOrCreate(
realm,
roomId,
roomMemberEvent.stateKey,
roomMemberEvent.type
).apply {
eventId = roomMemberEvent.eventId
root = eventEntity
}

View file

@ -89,7 +89,7 @@ internal class SendRelationWorker(context: Context, params: WorkerParameters)
roomId = roomId,
parentId = relatedEventId,
relationType = relationType,
eventType = localEvent.type,
eventType = localEvent.type!!,
content = localEvent.content
)
}

View file

@ -56,10 +56,10 @@ internal class LocalEchoRepository @Inject constructor(@SessionDatabase private
fun createLocalEcho(event: Event) {
val roomId = event.roomId ?: throw IllegalStateException("You should have set a roomId for your event")
val senderId = event.senderId ?: throw IllegalStateException("You should have set a senderIf for your event")
if (event.eventId == null) {
throw IllegalStateException("You should have set an eventId for your event")
}
val senderId = event.senderId ?: throw IllegalStateException("You should have set a senderId for your event")
event.eventId ?: throw IllegalStateException("You should have set an eventId for your event")
event.type ?: throw IllegalStateException("You should have set a type for your event")
val timelineEventEntity = realmSessionProvider.withRealm { realm ->
val eventEntity = event.toEntity(roomId, SendState.UNSENT, System.currentTimeMillis())
val roomMemberHelper = RoomMemberHelper(realm, roomId)

View file

@ -198,7 +198,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
// State event
if (roomSync.state?.events?.isNotEmpty() == true) {
for (event in roomSync.state.events) {
if (event.eventId == null || event.stateKey == null) {
if (event.eventId == null || event.stateKey == null || event.type == null) {
continue
}
val ageLocalTs = event.unsignedData?.age?.let { syncLocalTimestampMillis - it }
@ -254,7 +254,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
roomEntity.membership = Membership.INVITE
if (roomSync.inviteState != null && roomSync.inviteState.events.isNotEmpty()) {
roomSync.inviteState.events.forEach { event ->
if (event.stateKey == null) {
if (event.stateKey == null || event.type == null) {
return@forEach
}
val ageLocalTs = event.unsignedData?.age?.let { syncLocalTimestampMillis - it }
@ -281,7 +281,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
syncLocalTimestampMillis: Long): RoomEntity {
val roomEntity = RoomEntity.where(realm, roomId).findFirst() ?: realm.createObject(roomId)
for (event in roomSync.state?.events.orEmpty()) {
if (event.eventId == null || event.stateKey == null) {
if (event.eventId == null || event.stateKey == null || event.type == null) {
continue
}
val ageLocalTs = event.unsignedData?.age?.let { syncLocalTimestampMillis - it }
@ -293,7 +293,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
roomMemberEventHandler.handle(realm, roomId, event)
}
for (event in roomSync.timeline?.events.orEmpty()) {
if (event.eventId == null || event.senderId == null) {
if (event.eventId == null || event.senderId == null || event.type == null) {
continue
}
val ageLocalTs = event.unsignedData?.age?.let { syncLocalTimestampMillis - it }
@ -340,7 +340,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
val roomMemberContentsByUser = HashMap<String, RoomMemberContent?>()
for (event in eventList) {
if (event.eventId == null || event.senderId == null) {
if (event.eventId == null || event.senderId == null || event.type == null) {
continue
}
eventIds.add(event.eventId)

View file

@ -37,7 +37,7 @@ class RoomStateListController @Inject constructor(
override fun buildModels(data: RoomDevToolViewState?) {
when (data?.displayMode) {
RoomDevToolViewState.Mode.StateEventList -> {
val stateEventsGroups = data.stateEvents.invoke().orEmpty().groupBy { it.type }
val stateEventsGroups = data.stateEvents.invoke().orEmpty().groupBy { it.getClearType() }
if (stateEventsGroups.isEmpty()) {
noResultItem {

View file

@ -68,7 +68,7 @@ class NotifiableEventResolver @Inject constructor(private val stringProvider: St
// If the event can be displayed, display it as is
Timber.w("NotifiableEventResolver Received an unsupported event matching a bing rule")
// TODO Better event text display
val bodyPreview = event.type
val bodyPreview = event.type ?: EventType.MISSING_TYPE
return SimpleNotifiableEvent(
session.myUserId,