core: do not create decryption error chat items for earlier messages (#2189)

* core: do not create decryption error chat items for earlier messages

* do not report earlier error, mobile items, fix tests
This commit is contained in:
Evgeny Poberezkin
2023-04-16 19:30:25 +02:00
committed by GitHub
parent 393238f47c
commit 5b4c183466
10 changed files with 31 additions and 29 deletions

View File

@@ -1466,10 +1466,10 @@ data class ChatItem (
file = null
)
fun invalidJSON(json: String): ChatItem =
fun invalidJSON(chatDir: CIDirection?, meta: CIMeta?, json: String): ChatItem =
ChatItem(
chatDir = CIDirection.DirectSnd(),
meta = CIMeta.invalidJSON(),
chatDir = chatDir ?: CIDirection.DirectSnd(),
meta = meta ?: CIMeta.invalidJSON(),
content = CIContent.InvalidJSON(json),
quotedItem = null,
file = null
@@ -1681,13 +1681,11 @@ sealed class CIContent: ItemContent {
@Serializable
enum class MsgDecryptError {
@SerialName("ratchetHeader") RatchetHeader,
@SerialName("earlier") Earlier,
@SerialName("tooManySkipped") TooManySkipped;
val text: String get() = when (this) {
RatchetHeader -> generalGetString(R.string.decryption_error_permanent)
Earlier -> generalGetString(R.string.decryption_error)
TooManySkipped -> generalGetString(R.string.decryption_error_permanent)
RatchetHeader -> generalGetString(R.string.decryption_error)
TooManySkipped -> generalGetString(R.string.decryption_error)
}
}

View File

@@ -3011,9 +3011,15 @@ private fun parseChatData(chat: JsonElement): Chat {
?: ChatInfo.InvalidJSON(json.encodeToString(chat.jsonObject["chatInfo"]))
val chatStats = decodeObject(Chat.ChatStats.serializer(), chat.jsonObject["chatStats"])!!
val chatItems: List<ChatItem> = chat.jsonObject["chatItems"]!!.jsonArray.map {
decodeObject(ChatItem.serializer(), it) ?: ChatItem.invalidJSON(json.encodeToString(it))
decodeObject(ChatItem.serializer(), it) ?: parseChatItem(it)
}
return Chat(chatInfo, chatItems, chatStats)
return Chat(chatInfo, chatItems, chatStats)
}
private fun parseChatItem(j: JsonElement): ChatItem {
val chatDir: CIDirection? = decodeObject(CIDirection.serializer(), j.jsonObject["chatDir"])
val meta: CIMeta? = decodeObject(CIMeta.serializer(), j.jsonObject["meta"])
return ChatItem.invalidJSON(chatDir, meta, json.encodeToString(j))
}
private fun <T> decodeObject(deserializer: DeserializationStrategy<T>, obj: JsonElement?): T? =

View File

@@ -15,8 +15,6 @@ fun CIRcvDecryptionError(msgDecryptError: MsgDecryptError, msgCount: UInt, ci: C
MsgDecryptError.RatchetHeader -> String.format(generalGetString(R.string.alert_text_decryption_error_header), msgCount.toLong()) + "\n" +
generalGetString(R.string.alert_text_fragment_encryption_out_of_sync_old_database) + "\n" +
generalGetString(R.string.alert_text_fragment_permanent_error_reconnect)
MsgDecryptError.Earlier -> String.format(generalGetString(R.string.alert_text_decryption_error_earlier), msgCount.toLong()) + "\n" +
generalGetString(R.string.alert_text_fragment_encryption_out_of_sync_old_database)
MsgDecryptError.TooManySkipped -> String.format(generalGetString(R.string.alert_text_decryption_error_too_many_skipped), msgCount.toLong()) + "\n" +
generalGetString(R.string.alert_text_fragment_encryption_out_of_sync_old_database) + "\n" +
generalGetString(R.string.alert_text_fragment_permanent_error_reconnect)

View File

@@ -32,7 +32,6 @@
<string name="moderated_description">moderated</string>
<string name="invalid_chat">invalid chat</string>
<string name="invalid_data">invalid data</string>
<string name="decryption_error_permanent">Permanent decryption error</string>
<string name="decryption_error">Decryption error</string>
<!-- PendingContactConnection - ChatModel.kt -->
@@ -749,7 +748,6 @@
<string name="alert_title_msg_bad_id">Bad message ID</string>
<string name="alert_text_msg_bad_id">The ID of the next message is incorrect (less or equal to the previous).\nIt can happen because of some bug or when the connection is compromised.</string>
<string name="alert_text_decryption_error_header"><xliff:g id="message count" example="1">%1$d</xliff:g> messages failed to decrypt.</string>
<string name="alert_text_decryption_error_earlier"><xliff:g id="message count" example="1">%1$d</xliff:g> messages failed to decrypt and won\'t be shown.</string>
<string name="alert_text_decryption_error_too_many_skipped"><xliff:g id="message count" example="1">%1$d</xliff:g> messages skipped.</string>
<string name="alert_text_fragment_encryption_out_of_sync_old_database">It can happen when you or your connection used the old database backup.</string>
<string name="alert_text_fragment_permanent_error_reconnect">This error is permanent for this connection, please re-connect.</string>

View File

@@ -25,8 +25,6 @@ struct CIRcvDecryptionError: View {
switch msgDecryptError {
case .ratchetHeader:
message = Text("\(msgCount) messages failed to decrypt.") + Text("\n") + why + Text("\n") + permanent
case .earlier:
message = Text("\(msgCount) messages failed to decrypt and won't be shown.") + Text("\n") + why
case .tooManySkipped:
message = Text("\(msgCount) messages skipped.") + Text("\n") + why + Text("\n") + permanent
}

View File

@@ -174,7 +174,11 @@ func parseChatData(_ jChat: Any) throws -> ChatData {
if let ci: ChatItem = try? decodeObject(jCI) {
return ci
}
return ChatItem.invalidJSON(prettyJSON(jCI) ?? "")
return ChatItem.invalidJSON(
chatDir: decodeProperty(jCI, "chatDir"),
meta: decodeProperty(jCI, "meta"),
json: prettyJSON(jCI) ?? ""
)
}
return ChatData(chatInfo: chatInfo, chatItems: chatItems, chatStats: chatStats)
}
@@ -183,6 +187,13 @@ func decodeObject<T: Decodable>(_ obj: Any) throws -> T {
try jsonDecoder.decode(T.self, from: JSONSerialization.data(withJSONObject: obj))
}
func decodeProperty<T: Decodable>(_ obj: Any, _ prop: NSString) -> T? {
if let jProp = (obj as? NSDictionary)?[prop] {
return try? decodeObject(jProp)
}
return nil
}
func prettyJSON(_ obj: Any) -> String? {
if let d = try? JSONSerialization.data(withJSONObject: obj, options: .prettyPrinted) {
return String(decoding: d, as: UTF8.self)

View File

@@ -1943,10 +1943,10 @@ public struct ChatItem: Identifiable, Decodable {
return item
}
public static func invalidJSON(_ json: String) -> ChatItem {
public static func invalidJSON(chatDir: CIDirection?, meta: CIMeta?, json: String) -> ChatItem {
ChatItem(
chatDir: CIDirection.directSnd,
meta: CIMeta.invalidJSON,
chatDir: chatDir ?? .directSnd,
meta: meta ?? .invalidJSON,
content: .invalidJSON(json: json),
quotedItem: nil,
file: nil
@@ -2178,13 +2178,11 @@ public enum CIContent: Decodable, ItemContent {
public enum MsgDecryptError: String, Decodable {
case ratchetHeader
case earlier
case tooManySkipped
var text: String {
switch self {
case .ratchetHeader: return NSLocalizedString("Permanent decryption error", comment: "message decrypt error item")
case .earlier: return NSLocalizedString("Decryption error", comment: "message decrypt error item")
case .tooManySkipped: return NSLocalizedString("Permanent decryption error", comment: "message decrypt error item")
}
}