Pārlūkot izejas kodu

Fix handling of long lines.

If we multiple long lines in succession the start index got
miscalculated and part of the latter lines discarded.
tags/v0.10.2
Chris Smith 5 gadus atpakaļ
vecāks
revīzija
eacdf03763

+ 3
- 0
CHANGELOG Parādīt failu

1
 vNEXT (in development)
1
 vNEXT (in development)
2
 
2
 
3
+ * Fix handling of multiple long lines sometimes dropping part of the line
4
+ * Support lines with 8191 bytes of tags, as allowed by the message-tags spec
5
+
3
 v0.10.1
6
 v0.10.1
4
 
7
 
5
  * Added NickChangeFailed event for when nicknames are in use, banned, etc
8
  * Added NickChangeFailed event for when nicknames are in use, banned, etc

+ 10
- 10
src/main/kotlin/com/dmdirc/ktirc/io/LineBufferedSocket.kt Parādīt failu

80
 
80
 
81
     override val receiveChannel
81
     override val receiveChannel
82
         get() = produce {
82
         get() = produce {
83
-            val lineBuffer = ByteArray(4096)
84
-            var index = 0
83
+            val lineBuffer = ByteArray(16384)
84
+            var nextByteOffset = 0
85
             while (!readChannel.isClosedForRead) {
85
             while (!readChannel.isClosedForRead) {
86
-                var start = index
87
-                val count = readChannel.readAvailable(lineBuffer, index, lineBuffer.size - index)
88
-                for (i in index until index + count) {
86
+                var lineStart = 0
87
+                val bytesRead = readChannel.readAvailable(lineBuffer, nextByteOffset, lineBuffer.size - nextByteOffset)
88
+                for (i in nextByteOffset until nextByteOffset + bytesRead) {
89
                     if (lineBuffer[i] == CARRIAGE_RETURN || lineBuffer[i] == LINE_FEED) {
89
                     if (lineBuffer[i] == CARRIAGE_RETURN || lineBuffer[i] == LINE_FEED) {
90
-                        if (start < i) {
91
-                            val line = lineBuffer.sliceArray(start until i)
90
+                        if (lineStart < i) {
91
+                            val line = lineBuffer.sliceArray(lineStart until i)
92
                             log.fine { "<<< ${String(line)}" }
92
                             log.fine { "<<< ${String(line)}" }
93
                             send(line)
93
                             send(line)
94
                         }
94
                         }
95
-                        start = i + 1
95
+                        lineStart = i + 1
96
                     }
96
                     }
97
                 }
97
                 }
98
-                lineBuffer.copyInto(lineBuffer, 0, start)
99
-                index = count + index - start
98
+                lineBuffer.copyInto(lineBuffer, 0, lineStart)
99
+                nextByteOffset += bytesRead - lineStart
100
             }
100
             }
101
         }
101
         }
102
 
102
 

+ 19
- 0
src/test/kotlin/com/dmdirc/ktirc/io/KtorLineBufferedSocketTest.kt Parādīt failu

113
         }
113
         }
114
     }
114
     }
115
 
115
 
116
+    @Test
117
+    fun `KtorLineBufferedSocket can receive multiple long lines of text`() = runBlocking {
118
+        ServerSocket(12321).use { serverSocket ->
119
+            val socket = KtorLineBufferedSocket(GlobalScope, "localhost", 12321)
120
+            val line1 = "abcdefghijklmnopqrstuvwxyz".repeat(500)
121
+            val line2 = "1234567890987654321[];'#,.".repeat(500)
122
+            val line3 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".repeat(500)
123
+            GlobalScope.launch {
124
+                serverSocket.accept().getOutputStream().write("$line1\r\n$line2\r$line3\n".toByteArray())
125
+            }
126
+
127
+            socket.connect()
128
+            val lineProducer = socket.receiveChannel
129
+            assertEquals(line1, String(lineProducer.receive()))
130
+            assertEquals(line2, String(lineProducer.receive()))
131
+            assertEquals(line3, String(lineProducer.receive()))
132
+        }
133
+    }
134
+
116
     @Test
135
     @Test
117
     fun `KtorLineBufferedSocket can receive one line of text over multiple packets`() = runBlocking {
136
     fun `KtorLineBufferedSocket can receive one line of text over multiple packets`() = runBlocking {
118
         ServerSocket(12321).use { serverSocket ->
137
         ServerSocket(12321).use { serverSocket ->

Notiek ielāde…
Atcelt
Saglabāt