From 856e1a89ac73be6cde0dad979d0b8af8c1f2c771 Mon Sep 17 00:00:00 2001 From: sabeeh Date: Mon, 1 Jan 2024 22:05:30 +0500 Subject: [PATCH 1/6] url test cases added --- korge-core/test/korlibs/io/net/URLTest.kt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/korge-core/test/korlibs/io/net/URLTest.kt b/korge-core/test/korlibs/io/net/URLTest.kt index b874768be7..904d82669d 100644 --- a/korge-core/test/korlibs/io/net/URLTest.kt +++ b/korge-core/test/korlibs/io/net/URLTest.kt @@ -115,6 +115,18 @@ class URLTest { assertEquals("https", url2.scheme) assertEquals(443, url2.port) assertEquals("https://Google.com", url2.fullUrl) + + val url3 = URL("https://username:password@example.com:8443/path/to/resource?q=1") + assertEquals("https", url3.scheme) + assertEquals("username:password", url3.userInfo) + assertEquals("username", url3.user) + assertEquals("password", url3.password) + assertEquals("example.com", url3.host) + assertEquals(8443, url3.port) + assertEquals("/path/to/resource", url3.path) + assertEquals("/path/to/resource?q=1", url3.pathWithQuery) + assertEquals("q=1", url3.query) + assertEquals("https://username:password@example.com:8443/path/to/resource?q=1", url3.fullUrl) } @Test From de1418ecc9530d070adb4d7cea51aaba2209b20f Mon Sep 17 00:00:00 2001 From: sabeeh Date: Mon, 1 Jan 2024 22:07:07 +0500 Subject: [PATCH 2/6] fix CharReaderFromSyncStream to read less than chunkSize (fixes #2108) --- .../src/korlibs/io/stream/CharReader.kt | 39 ++++++++++----- .../test/korlibs/io/stream/CharReaderTest.kt | 48 +++++++++++++++++++ 2 files changed, 76 insertions(+), 11 deletions(-) diff --git a/korge-core/src/korlibs/io/stream/CharReader.kt b/korge-core/src/korlibs/io/stream/CharReader.kt index caf6bf75df..481970e060 100644 --- a/korge-core/src/korlibs/io/stream/CharReader.kt +++ b/korge-core/src/korlibs/io/stream/CharReader.kt @@ -13,33 +13,50 @@ fun ByteArray.toCharReader(charset: Charset, chunkSize: Int = 1024): CharReader fun SyncStream.toCharReader(charset: Charset, chunkSize: Int = 1024): CharReader = CharReaderFromSyncStream(this, charset, chunkSize) -class CharReaderFromSyncStream(val stream: SyncStream, val charset: Charset, val chunkSize: Int = 1024) : CharReader { +class CharReaderFromSyncStream(val stream: SyncStream, val charset: Charset, val chunkSize: Int = DEFAULT_CHUNK_SIZE) : CharReader { private val temp = ByteArray(chunkSize) private val buffer = ByteArrayDeque() private var tempStringBuilder = StringBuilder() + init { + if (chunkSize < MIN_CHUNK_SIZE) throw IllegalArgumentException("chunkSize must be greater than $MIN_CHUNK_SIZE") + } + override fun clone(): CharReader = CharReaderFromSyncStream(stream.clone(), charset, chunkSize) override fun read(out: StringBuilder, count: Int): Int { - while (buffer.availableRead < temp.size) { - val readCount = stream.read(temp) - if (readCount <= 0) break - buffer.write(temp, 0, readCount) - } - + bufferUp() while (tempStringBuilder.length < count) { val readCount = buffer.peek(temp) val consumed = charset.decode(tempStringBuilder, temp, 0, readCount) - if (consumed <= 0) break - buffer.skip(consumed) + if (consumed <= 0) { + if (bufferUp() <= 0) break + } else { + buffer.skip(consumed) + } } - //println("tempStringBuilder=$tempStringBuilder") - val slice = tempStringBuilder.substring(0, kotlin.math.min(count, tempStringBuilder.length)) tempStringBuilder = StringBuilder(slice.length).append(tempStringBuilder.substring(slice.length)) out.append(slice) return slice.length } + + private fun bufferUp(): Int { + var totalReadCount = 0 + while (buffer.availableRead < temp.size) { + val readCount = stream.read(temp) + if (readCount <= 0) break + totalReadCount += readCount + buffer.write(temp, 0, readCount) + } + + return totalReadCount + } + + companion object { + private const val DEFAULT_CHUNK_SIZE = 1024 + private const val MIN_CHUNK_SIZE = 8 + } } diff --git a/korge-core/test/korlibs/io/stream/CharReaderTest.kt b/korge-core/test/korlibs/io/stream/CharReaderTest.kt index 68671f5ef9..e7101f32c6 100644 --- a/korge-core/test/korlibs/io/stream/CharReaderTest.kt +++ b/korge-core/test/korlibs/io/stream/CharReaderTest.kt @@ -9,4 +9,52 @@ class CharReaderTest { val reader = "áéíóúñ".toByteArray(UTF8).toCharReader(UTF8) assertEquals("á,éí,óúñ", listOf(reader.read(1), reader.read(2), reader.read(10)).joinToString(",")) } + + + @Test + fun test2() { + val reader = "áéíóúñ".repeat(10000).toByteArray(UTF8).toCharReader(charset = UTF8, chunkSize = 8) + assertEquals("á,éí,óúñ", listOf(reader.read(1), reader.read(2), reader.read(3)).joinToString(",")) + } + + @Test + fun testMixCharReader() { + val loop = 2000 + val data = "ää" + val inputData = data.repeat(loop) + for (chunkSize in 8 until 2000) { + val charReader = inputData.openSync().toCharReader(charset = Charsets.UTF8, chunkSize = chunkSize) + repeat(loop) { + assertEquals(data, charReader.read(data.length), "error: $it, chunkSize: $chunkSize") + } + assertEquals("", charReader.read(1)) + } + } + + @Test + fun testCharReaderMarkSkipReset() { + val randomStrings = listOf( + "©頷ӨҤもタ編倏病Ҿ0沑âチ麕üӨҀ🙌とガӃ🙄Ҥzせø觧ҥ", + "Ђヹ肯みцë匓ンê😺り磬バëӇØ゚琫ら儂脸😨D亢JZEÕキ燗😨🙉ュӼ`ぺ", + "😳捇😗Ҧヿィ😲😵SӚåぐルҩS😯yѹ=ӪӠÀrキえÄ🙎へ¶Mたじ😞冃😃a\\xa0ÙҒ樗ボ😨", + "らーçウごネ粦😓õ姗ӏ(", + "Sm糛҆Òう楢ょ😽ê.", + "X5O!P%@AP[4\\PZX54(P^)7CC)7}\$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!\$H+H*", + "abcdefghijklm" + ) + (1..30).forEach { readCount -> + randomStrings.forEach { inputData -> + val dataSegments: List = inputData.splitInChunks(readCount) + + for (chunkSize in 8 until 2000) { + val charReader = inputData.openSync().toCharReader(charset = Charsets.UTF8, chunkSize = chunkSize) + dataSegments.forEach { data -> + val strBuilder = StringBuilder() + assertEquals(data.length, charReader.read(strBuilder, readCount)) + assertEquals(data, strBuilder.toString()) + } + } + } + } + } } From 52773e5ca11b8d9a46c720e0aa279bcdd8835889 Mon Sep 17 00:00:00 2001 From: sabeeh Date: Mon, 1 Jan 2024 22:43:17 +0500 Subject: [PATCH 3/6] CharReader tests updated --- .../test/korlibs/io/stream/CharReaderTest.kt | 24 +++++-------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/korge-core/test/korlibs/io/stream/CharReaderTest.kt b/korge-core/test/korlibs/io/stream/CharReaderTest.kt index e7101f32c6..f9d45f2945 100644 --- a/korge-core/test/korlibs/io/stream/CharReaderTest.kt +++ b/korge-core/test/korlibs/io/stream/CharReaderTest.kt @@ -13,34 +13,21 @@ class CharReaderTest { @Test fun test2() { - val reader = "áéíóúñ".repeat(10000).toByteArray(UTF8).toCharReader(charset = UTF8, chunkSize = 8) + val reader = "áéíóúñ".repeat(10).toByteArray(UTF8).toCharReader(charset = UTF8, chunkSize = 8) assertEquals("á,éí,óúñ", listOf(reader.read(1), reader.read(2), reader.read(3)).joinToString(",")) } @Test - fun testMixCharReader() { - val loop = 2000 - val data = "ää" - val inputData = data.repeat(loop) - for (chunkSize in 8 until 2000) { - val charReader = inputData.openSync().toCharReader(charset = Charsets.UTF8, chunkSize = chunkSize) - repeat(loop) { - assertEquals(data, charReader.read(data.length), "error: $it, chunkSize: $chunkSize") - } - assertEquals("", charReader.read(1)) - } - } - - @Test - fun testCharReaderMarkSkipReset() { + fun testCharReaderWithRandomStrings() { val randomStrings = listOf( + "abcdefghijklm", + "ää", "©頷ӨҤもタ編倏病Ҿ0沑âチ麕üӨҀ🙌とガӃ🙄Ҥzせø觧ҥ", "Ђヹ肯みцë匓ンê😺り磬バëӇØ゚琫ら儂脸😨D亢JZEÕキ燗😨🙉ュӼ`ぺ", "😳捇😗Ҧヿィ😲😵SӚåぐルҩS😯yѹ=ӪӠÀrキえÄ🙎へ¶Mたじ😞冃😃a\\xa0ÙҒ樗ボ😨", "らーçウごネ粦😓õ姗ӏ(", "Sm糛҆Òう楢ょ😽ê.", - "X5O!P%@AP[4\\PZX54(P^)7CC)7}\$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!\$H+H*", - "abcdefghijklm" + "X5O!P%@AP[4\\PZX54(P^)7CC)7}\$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!\$H+H*" ) (1..30).forEach { readCount -> randomStrings.forEach { inputData -> @@ -53,6 +40,7 @@ class CharReaderTest { assertEquals(data.length, charReader.read(strBuilder, readCount)) assertEquals(data, strBuilder.toString()) } + assertEquals("", charReader.read(1)) // stream is empty all chars already read } } } From af2aead3b83cce59a4466cae283b742d79c2c511 Mon Sep 17 00:00:00 2001 From: sabeeh Date: Tue, 2 Jan 2024 00:50:38 +0500 Subject: [PATCH 4/6] Move the URLTest code to another pull request (PR). --- korge-core/test/korlibs/io/net/URLTest.kt | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/korge-core/test/korlibs/io/net/URLTest.kt b/korge-core/test/korlibs/io/net/URLTest.kt index 904d82669d..b874768be7 100644 --- a/korge-core/test/korlibs/io/net/URLTest.kt +++ b/korge-core/test/korlibs/io/net/URLTest.kt @@ -115,18 +115,6 @@ class URLTest { assertEquals("https", url2.scheme) assertEquals(443, url2.port) assertEquals("https://Google.com", url2.fullUrl) - - val url3 = URL("https://username:password@example.com:8443/path/to/resource?q=1") - assertEquals("https", url3.scheme) - assertEquals("username:password", url3.userInfo) - assertEquals("username", url3.user) - assertEquals("password", url3.password) - assertEquals("example.com", url3.host) - assertEquals(8443, url3.port) - assertEquals("/path/to/resource", url3.path) - assertEquals("/path/to/resource?q=1", url3.pathWithQuery) - assertEquals("q=1", url3.query) - assertEquals("https://username:password@example.com:8443/path/to/resource?q=1", url3.fullUrl) } @Test From f0561b5c8fe159962c10eb61f293b0ad1ac298dc Mon Sep 17 00:00:00 2001 From: sabeeh Date: Tue, 2 Jan 2024 00:55:23 +0500 Subject: [PATCH 5/6] test added for MIN_CHUNK_SIZE exception check --- korge-core/test/korlibs/io/stream/CharReaderTest.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/korge-core/test/korlibs/io/stream/CharReaderTest.kt b/korge-core/test/korlibs/io/stream/CharReaderTest.kt index f9d45f2945..39c2aefffd 100644 --- a/korge-core/test/korlibs/io/stream/CharReaderTest.kt +++ b/korge-core/test/korlibs/io/stream/CharReaderTest.kt @@ -15,6 +15,9 @@ class CharReaderTest { fun test2() { val reader = "áéíóúñ".repeat(10).toByteArray(UTF8).toCharReader(charset = UTF8, chunkSize = 8) assertEquals("á,éí,óúñ", listOf(reader.read(1), reader.read(2), reader.read(3)).joinToString(",")) + + assertFailsWith { "áéíóúñ".toByteArray(UTF8).toCharReader(charset = UTF8, chunkSize = CharReaderFromSyncStream.MIN_CHUNK_SIZE -1) } + } @Test From 9fb94db82a6c9e97832fac11c8d6c0e58cce4a48 Mon Sep 17 00:00:00 2001 From: sabeeh Date: Tue, 2 Jan 2024 00:57:13 +0500 Subject: [PATCH 6/6] chunk size validation to with require --- korge-core/src/korlibs/io/stream/CharReader.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/korge-core/src/korlibs/io/stream/CharReader.kt b/korge-core/src/korlibs/io/stream/CharReader.kt index 481970e060..d925b87a3e 100644 --- a/korge-core/src/korlibs/io/stream/CharReader.kt +++ b/korge-core/src/korlibs/io/stream/CharReader.kt @@ -19,7 +19,7 @@ class CharReaderFromSyncStream(val stream: SyncStream, val charset: Charset, val private var tempStringBuilder = StringBuilder() init { - if (chunkSize < MIN_CHUNK_SIZE) throw IllegalArgumentException("chunkSize must be greater than $MIN_CHUNK_SIZE") + require(chunkSize >= MIN_CHUNK_SIZE) { "chunkSize must be greater than $MIN_CHUNK_SIZE, was $chunkSize" } } override fun clone(): CharReader = CharReaderFromSyncStream(stream.clone(), charset, chunkSize) @@ -56,7 +56,7 @@ class CharReaderFromSyncStream(val stream: SyncStream, val charset: Charset, val } companion object { - private const val DEFAULT_CHUNK_SIZE = 1024 - private const val MIN_CHUNK_SIZE = 8 + const val DEFAULT_CHUNK_SIZE = 1024 + const val MIN_CHUNK_SIZE = 8 } }