You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Value hierarchy tries to use most of the available serialization API and test it on all main data types available on Kotlin/JVM.
The exact implementation details are not important in most cases. We will highlight interesting implementation details whenever necessary.
CBOR bugs are mainly due to unhandled internal exceptions that should not be displayed to the user in the raw format.
1. Unhandled IllegalStateException
Byte 126 is interpreted as "read a string of 30 characters"
@Test
fun`unhandled illegal state exception`() {
val byteArray = byteArrayOf(126)
val serializer =Cbor.Default// Fails with "java.lang.IllegalStateException: Unexpected EOF, available 0 bytes, requested: 30"
assertThrows<SerializationException> {
serializer.decodeFromByteArray<String>(byteArray)
}
}
2. Unhandled NegativeArraySizeException
Byte 40 is interpreted as an instruction to read -9 bytes.
@Test
fun`unhandled negative array size exception`() {
val byteArray = byteArrayOf(127, 40)
val serializer =Cbor.Default// Fails with "java.lang.NegativeArraySizeException: -9"
assertThrows<SerializationException> {
serializer.decodeFromByteArray<String>(byteArray)
}
}
3. Unhandled StackOverflowError
Root of issue:
CborParser class does not check for the end of the buffer
ByteArrayInput returns -1 on read if it has reached the end of the buffer
CborParser::readBytes interprets this -1 value as "read an indefinite number of bytes" and calls CborParser::readIndefiniteLengthBytes ; CborParser::readIndefiniteLengthBytes , meanwhile, calls CborParser::readBytes recursively
@Test
fun`unhandled stack overflow error`() {
val byteArray = byteArrayOf(127, 0, 0)
val serializer =Cbor.Default// Goes to infinite recursion:// at kotlinx.serialization.cbor.internal.CborParser.readBytes(Decoder.kt:247)// at kotlinx.serialization.cbor.internal.CborParser.readIndefiniteLengthBytes(Decoder.kt:514)
assertThrows<SerializationException> {
serializer.decodeFromByteArray<String>(byteArray)
}
}
4. Unhandled ArrayIndexOutOfBounds
Option ignoreUnknownKeys=true tells the parser to skip unknown elements.
Byte 122 at position 67 is interpreted as the start of the element and encodes its length of -272646673.
In an attempt to skip this element, the parser moved to -272646673 bytes "ahead" in ByteArrayInput and sets the
current position to -272646606.
If ignoreUnknownKeys=false, this will fail with "kotlinx.serialization.cbor.internal.CborDecodingException: CborLabel unknown: 31 for obj(status: kotlin.String, value: kotlin.collections.LinkedHashMap)"
0. Setup
We created the following class hierarchy for testing serialization library:
Value
hierarchy tries to use most of the available serialization API and test it on all main data types available on Kotlin/JVM.The exact implementation details are not important in most cases. We will highlight interesting implementation details whenever necessary.
CBOR bugs are mainly due to unhandled internal exceptions that should not be displayed to the user in the raw format.
1. Unhandled
IllegalStateException
Byte
126
is interpreted as "read a string of 30 characters"2. Unhandled
NegativeArraySizeException
Byte
40
is interpreted as an instruction to read-9
bytes.3. Unhandled
StackOverflowError
Root of issue:
CborParser
class does not check for the end of the bufferByteArrayInput
returns-1
on read if it has reached the end of the bufferCborParser::readBytes
interprets this-1
value as "read an indefinite number of bytes" and callsCborParser::readIndefiniteLengthBytes
;CborParser::readIndefiniteLengthBytes
, meanwhile, callsCborParser::readBytes
recursively4. Unhandled
ArrayIndexOutOfBounds
Option
ignoreUnknownKeys=true
tells the parser to skip unknown elements.Byte
122
at position 67 is interpreted as the start of the element and encodes its length of-272646673
.In an attempt to skip this element, the parser moved to
-272646673
bytes "ahead" inByteArrayInput
and sets thecurrent position to
-272646606
.If
ignoreUnknownKeys=false
, this will fail with"kotlinx.serialization.cbor.internal.CborDecodingException: CborLabel unknown: 31 for obj(status: kotlin.String, value: kotlin.collections.LinkedHashMap)"
Bugs are found by fuzzing team @ PLAN Lab
Environment
The text was updated successfully, but these errors were encountered: