From 24e1f8ddb34b26d84d6f13ca58d2011a65324a8f Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Sat, 31 Mar 2018 22:44:52 +0200
Subject: [PATCH] Handle avatars with unverified idents

---
 .../ui/chat/messages/DisplayMessage.kt        |  2 +-
 .../kuschku/libquassel/protocol/QVariant.kt   | 43 ++++++++---
 .../quassel/syncables/CertManager.kt          |  2 -
 .../kuschku/libquassel/ConnectionUnitTest.kt  | 25 ++++--
 .../kuschku/libquassel/SerializerUnitTest.kt  | 76 -------------------
 .../viewmodel/QuasselViewModel.kt             |  2 +-
 6 files changed, 52 insertions(+), 98 deletions(-)

diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/DisplayMessage.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/DisplayMessage.kt
index 8a3f6fb43..978800331 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/DisplayMessage.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/DisplayMessage.kt
@@ -20,7 +20,7 @@ data class DisplayMessage(
 
   val tag = Tag(content.messageId, content.followUp, isSelected, isExpanded, isMarkerLine)
   val avatarUrl = content.sender.let {
-    Regex("[us]id(\\d+)").matchEntire(HostmaskHelper.user(it))?.groupValues?.lastOrNull()?.let {
+    Regex("~?[us]id(\\d+)").matchEntire(HostmaskHelper.user(it))?.groupValues?.lastOrNull()?.let {
       "https://www.irccloud.com/avatar-redirect/$it"
     }
   }
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/QVariant.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/QVariant.kt
index e70c2ab8d..8018c79d7 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/QVariant.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/QVariant.kt
@@ -1,18 +1,46 @@
 package de.kuschku.libquassel.protocol
 
 import de.kuschku.libquassel.protocol.primitive.serializer.Serializer
-import java.nio.ByteBuffer
-import java.nio.CharBuffer
 
 sealed class QVariant<T> constructor(val data: T?, val type: Type, val serializer: Serializer<T>) {
   class Typed<T> internal constructor(data: T?, type: Type, serializer: Serializer<T>) :
     QVariant<T>(data, type, serializer) {
-    override fun toString() = "QVariant.Typed(${type.serializableName}, ${toString(data)})"
+    override fun toString() = "QVariant.Typed(${type.serializableName}, $data})"
+    override fun equals(other: Any?): Boolean {
+      if (this === other) return true
+      if (other !is Typed<*>) return false
+
+      if (data != other.data) return false
+      if (type != other.type) return false
+
+      return true
+    }
+
+    override fun hashCode(): Int {
+      var result = data?.hashCode() ?: 0
+      result = 31 * result + type.hashCode()
+      return result
+    }
   }
 
   class Custom<T> internal constructor(data: T?, val qtype: QType, serializer: Serializer<T>) :
     QVariant<T>(data, qtype.type, serializer) {
-    override fun toString() = "QVariant.Custom($qtype, ${toString(data)})"
+    override fun toString() = "QVariant.Custom($qtype, $data)"
+    override fun equals(other: Any?): Boolean {
+      if (this === other) return true
+      if (other !is Custom<*>) return false
+
+      if (data != other.data) return false
+      if (qtype != other.qtype) return false
+
+      return true
+    }
+
+    override fun hashCode(): Int {
+      var result = data?.hashCode() ?: 0
+      result = 31 * result + qtype.hashCode()
+      return result
+    }
   }
 
   fun or(defValue: T): T {
@@ -29,13 +57,6 @@ sealed class QVariant<T> constructor(val data: T?, val type: Type, val serialize
   }
 }
 
-inline fun toString(data: Any?) = when (data) {
-  is ByteBuffer -> data.array()?.contentToString()
-  is CharBuffer -> data.array()?.contentToString()
-  is Array<*>   -> data.contentToString()
-  else          -> data.toString()
-}
-
 inline fun <reified U> QVariant_?.value(): U? = this?.value<U?>(null)
 
 inline fun <reified U> QVariant_?.value(defValue: U): U = this?.data as? U ?: defValue
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/CertManager.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/CertManager.kt
index a35d0cbfa..604f0ed8b 100644
--- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/CertManager.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/CertManager.kt
@@ -34,12 +34,10 @@ class CertManager constructor(
 
   override fun setSslCert(encoded: ByteBuffer?) {
     _sslCert = encoded
-    super.setSslCert(encoded)
   }
 
   override fun setSslKey(encoded: ByteBuffer?) {
     _sslKey = encoded
-    super.setSslKey(encoded)
   }
 
   private var _sslKey: ByteBuffer? = null
diff --git a/lib/src/test/java/de/kuschku/libquassel/ConnectionUnitTest.kt b/lib/src/test/java/de/kuschku/libquassel/ConnectionUnitTest.kt
index f2b187560..bd816b742 100644
--- a/lib/src/test/java/de/kuschku/libquassel/ConnectionUnitTest.kt
+++ b/lib/src/test/java/de/kuschku/libquassel/ConnectionUnitTest.kt
@@ -1,7 +1,20 @@
 package de.kuschku.libquassel
 
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.quassel.ProtocolFeature
+import de.kuschku.libquassel.quassel.QuasselFeatures
+import de.kuschku.libquassel.session.BacklogStorage
+import de.kuschku.libquassel.session.Session
+import de.kuschku.libquassel.session.SocketAddress
+import de.kuschku.libquassel.util.compatibility.reference.JavaHandlerService
+import org.junit.BeforeClass
+import org.junit.Test
+import org.threeten.bp.Instant
+import java.security.cert.X509Certificate
+import java.util.logging.LogManager
+import javax.net.ssl.X509TrustManager
+
 class ConnectionUnitTest {
-/*
   companion object {
     @JvmStatic
     @BeforeClass
@@ -21,10 +34,10 @@ class ConnectionUnitTest {
       ClientData(
         identifier = "libquassel test",
         buildDate = Instant.EPOCH,
-        clientFeatures = Quassel_Feature.of(*LegacyFeature.validValues),
+        clientFeatures = QuasselFeatures.all(),
         protocolFeatures = Protocol_Feature.of(ProtocolFeature.TLS, ProtocolFeature.Compression),
-        supportedProtocols = listOf(Protocol.Datastream),
-        ), object : X509TrustManager {
+        supportedProtocols = listOf(Protocol.Datastream)
+      ), object : X509TrustManager {
       override fun checkClientTrusted(p0: Array<out X509Certificate>?, p1: String?) {
       }
 
@@ -38,9 +51,7 @@ class ConnectionUnitTest {
       override fun clearMessages(bufferId: BufferId, idRange: IntRange) = Unit
       override fun clearMessages(bufferId: BufferId) = Unit
       override fun clearMessages() = Unit
-    }, user to pass,
-      ) {}
+    }, user to pass, {}, {})
     session.join()
   }
-*/
 }
\ No newline at end of file
diff --git a/lib/src/test/java/de/kuschku/libquassel/SerializerUnitTest.kt b/lib/src/test/java/de/kuschku/libquassel/SerializerUnitTest.kt
index 71ab8fe92..8f68cdbab 100644
--- a/lib/src/test/java/de/kuschku/libquassel/SerializerUnitTest.kt
+++ b/lib/src/test/java/de/kuschku/libquassel/SerializerUnitTest.kt
@@ -1,8 +1,5 @@
 package de.kuschku.libquassel
 
-import de.kuschku.libquassel.protocol.QType
-import de.kuschku.libquassel.protocol.QVariant
-import de.kuschku.libquassel.protocol.Type
 import de.kuschku.libquassel.protocol.primitive.serializer.*
 import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
@@ -106,79 +103,6 @@ class SerializerUnitTest {
     assertEquals("Test", roundTrip(StringSerializer.C, "Test"))
   }
 
-  @Test
-  fun variantListSerializer() {
-    val value = listOf(
-      QVariant.of(1, Type.Int),
-      QVariant.of(ByteBuffer.wrap(byteArrayOf(
-        66,
-        97,
-        99,
-        107,
-        108,
-        111,
-        103,
-        77,
-        97,
-        110,
-        97,
-        103,
-        101,
-        114,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0
-      )), Type.QByteArray),
-      QVariant.of(ByteBuffer.wrap(byteArrayOf(
-        114,
-        101,
-        113,
-        117,
-        101,
-        115,
-        116,
-        66,
-        97,
-        99,
-        107,
-        108,
-        111,
-        103,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0
-      )), Type.QByteArray),
-      QVariant.of(1873, QType.BufferId),
-      QVariant.of(-1, QType.MsgId),
-      QVariant.of(-1, QType.MsgId),
-      QVariant.of(20, Type.Int),
-      QVariant.of(0, Type.Int)
-    )
-    assert(value == roundTrip(VariantListSerializer, value))
-  }
-
   companion object {
     fun <T> roundTrip(serializer: Serializer<T>, value: T,
                       features: QuasselFeatures = QuasselFeatures.all()): T {
diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt
index 03af6d933..d8da0de01 100644
--- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt
+++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt
@@ -182,7 +182,7 @@ class QuasselViewModel : ViewModel() {
                       user.realName(),
                       user.isAway(),
                       network.support("CASEMAPPING"),
-                      Regex("[us]id(\\d+)").matchEntire(user.user())?.groupValues?.lastOrNull()?.let {
+                      Regex("~?[us]id(\\d+)").matchEntire(user.user())?.groupValues?.lastOrNull()?.let {
                         "https://www.irccloud.com/avatar-redirect/$it"
                       }
                     )
-- 
GitLab