Browse Source

Handle bad server timestamps

tags/v0.10.3
Chris Smith 5 years ago
parent
commit
23317f6cec

+ 1
- 0
CHANGELOG View File

@@ -1,6 +1,7 @@
1 1
 vNEXT (in development)
2 2
 
3 3
  * Fix issue parsing CTCPs when the content contained multi-byte chars
4
+ * If the server provides an invalid timestamp, the event now defaults to the current time
4 5
 
5 6
 v0.10.2
6 7
 

+ 11
- 6
src/main/kotlin/com/dmdirc/ktirc/model/IrcMessage.kt View File

@@ -3,17 +3,21 @@ package com.dmdirc.ktirc.model
3 3
 import com.dmdirc.ktirc.events.EventMetadata
4 4
 import com.dmdirc.ktirc.util.currentTimeProvider
5 5
 import com.dmdirc.ktirc.util.currentTimeZoneProvider
6
+import com.dmdirc.ktirc.util.logger
6 7
 import java.time.Instant
7 8
 import java.time.LocalDateTime
9
+import java.util.logging.Level
8 10
 
9 11
 /**
10 12
  * Represents an IRC protocol message.
11 13
  */
12 14
 internal class IrcMessage(val tags: Map<MessageTag, String>, val prefix: ByteArray?, val command: String, val params: List<ByteArray>) {
13 15
 
16
+    private val log by logger()
17
+
14 18
     /** The time at which the message was sent, or our best guess at it. */
15 19
     val metadata = EventMetadata(
16
-            time = time,
20
+            time = tags[MessageTag.ServerTime]?.toLocalDateOrNull() ?: currentTimeProvider(),
17 21
             batchId = tags[MessageTag.Batch],
18 22
             messageId = tags[MessageTag.MessageId],
19 23
             label = tags[MessageTag.Label])
@@ -25,11 +29,12 @@ internal class IrcMessage(val tags: Map<MessageTag, String>, val prefix: ByteArr
25 29
         }
26 30
     }
27 31
 
28
-    private val time
29
-        get() = when (MessageTag.ServerTime in tags) {
30
-            true -> LocalDateTime.ofInstant(Instant.parse(tags[MessageTag.ServerTime]), currentTimeZoneProvider())
31
-            false -> currentTimeProvider()
32
-        }
32
+    private fun String.toLocalDateOrNull() = try {
33
+        LocalDateTime.ofInstant(Instant.parse(this), currentTimeZoneProvider())
34
+    } catch(e: Exception) {
35
+        log.log(Level.WARNING, e) { "Received unparsable server-time tag: $this" }
36
+        null
37
+    }
33 38
 
34 39
 }
35 40
 

+ 11
- 4
src/test/kotlin/com/dmdirc/ktirc/model/IrcMessageTest.kt View File

@@ -12,21 +12,28 @@ import java.time.ZoneId
12 12
 internal class IrcMessageTest {
13 13
 
14 14
     @Test
15
-    fun `Gets UTC time from ServerTime tag if present`() {
15
+    fun `gets UTC time from ServerTime tag if present`() {
16 16
         currentTimeZoneProvider = { ZoneId.of("Z") }
17 17
         val message = IrcMessage(hashMapOf(MessageTag.ServerTime to "1995-09-15T09:00:00.0000Z"), null, "", emptyList())
18 18
         assertEquals(LocalDateTime.parse("1995-09-15T09:00:00"), message.metadata.time)
19 19
     }
20 20
 
21 21
     @Test
22
-    fun `Converts time in ServerTime tag to local timezone`() {
22
+    fun `converts time in ServerTime tag to local timezone`() {
23 23
         currentTimeZoneProvider = { ZoneId.of("America/New_York") }
24 24
         val message = IrcMessage(hashMapOf(MessageTag.ServerTime to "1995-09-15T09:00:00.0000Z"), null, "", emptyList())
25 25
         assertEquals(LocalDateTime.parse("1995-09-15T05:00:00"), message.metadata.time)
26 26
     }
27 27
 
28 28
     @Test
29
-    fun `Uses current local time if no tag present`() {
29
+    fun `uses current time if ServerTime tag is malformed`() {
30
+        currentTimeProvider = { TestConstants.time }
31
+        val message = IrcMessage(hashMapOf(MessageTag.ServerTime to "1996-05-03T13:00:00.***Z"), null, "", emptyList())
32
+        assertEquals(LocalDateTime.parse("1995-09-15T09:00:00"), message.metadata.time)
33
+    }
34
+
35
+    @Test
36
+    fun `uses current local time if no tag present`() {
30 37
         currentTimeProvider = { TestConstants.time }
31 38
         val message = IrcMessage(emptyMap(), null, "", emptyList())
32 39
         assertEquals(LocalDateTime.parse("1995-09-15T09:00:00"), message.metadata.time)
@@ -65,7 +72,7 @@ internal class IrcMessageTest {
65 72
     }
66 73
 
67 74
     @Test
68
-    fun `Uses account-name tag when creating a source user`() {
75
+    fun `uses account-name tag when creating a source user`() {
69 76
         val message = IrcMessage(hashMapOf(MessageTag.AccountName to "acidBurn"), "acidBurn!libby@root.localhost".toByteArray(), "", emptyList())
70 77
         val user = message.sourceUser!!
71 78
 

Loading…
Cancel
Save