Skip to content

Commit b1f8f70

Browse files
committed
fix(decoder): bad state transition when decode map like value
1 parent b6ebae3 commit b1f8f70

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

src/commonMain/kotlin/space/iseki/bencoding/BencodeDecoder0.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,16 @@ internal class BencodeDecoder0(
203203
if (s and C_READ == 0) {
204204
error("call decodeElementIndex before decode*")
205205
}
206-
stack[sp] = s xor C_READ
206+
stack[sp] = postReadStateOf(stack[sp])
207+
}
208+
}
209+
210+
private fun postReadStateOf(old: Int): Int {
211+
assert(old and C_READ != 0)
212+
return when (old) {
213+
MAP_KEY_READ -> MAP_VAL_IDLE
214+
MAP_VAL_READ -> MAP_KEY_IDLE
215+
else -> old xor C_READ
207216
}
208217
}
209218

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package space.iseki.bencoding
2+
3+
import kotlinx.serialization.decodeFromByteArray
4+
import kotlin.test.Test
5+
import kotlin.test.assertEquals
6+
7+
class MapLikeTest {
8+
val data = "d3:abci10e2:cdi-20ee"
9+
val value = mapOf("abc" to 10, "cd" to -20)
10+
11+
@Test
12+
fun testDecode() {
13+
val decoded = Bencode.decodeFromByteArray<Map<String, Int>>(data.encodeToByteArray())
14+
assertEquals(value, decoded)
15+
}
16+
17+
@Test
18+
fun testManyDecode() {
19+
val data = (0..100).joinToString("", prefix = "d", postfix = "e") { val k = "$it"; "${k.length}:${k}i${k}e" }
20+
val value = (0..100).associateBy { val k = "$it"; k }
21+
val decoded = Bencode.decodeFromByteArray<Map<String, Int>>(data.encodeToByteArray())
22+
assertEquals(value, decoded)
23+
}
24+
}

0 commit comments

Comments
 (0)