Skip to content

Documentation for serializer(KType) doesn't mention that it's unsound #2948

Closed
@dkhalanskyjb

Description

@dkhalanskyjb
import kotlinx.serialization.json.*
import kotlinx.serialization.*
import kotlin.reflect.*

fun main() {
    println(Json.encodeToString(serializer(typeOf<Double>()), "string"))
}

compiles just fine, but throws

Exception in thread "main" java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Number (java.lang.String and java.lang.Number are in module java.base of loader 'bootstrap')
	at kotlinx.serialization.internal.DoubleSerializer.serialize(Primitives.kt:113)
	at kotlinx.serialization.json.internal.StreamingJsonEncoder.encodeSerializableValue(StreamingJsonEncoder.kt:259)
	at kotlinx.serialization.json.internal.JsonStreamsKt.encodeByWriter(JsonStreams.kt:99)
	at kotlinx.serialization.json.Json.encodeToString(Json.kt:125)

The documentation doesn't mention the intended usage pattern (which is probably to do an unchecked cast of the result into a KSerializer of the required type?) and doesn't explain that the returned value is prone to crashes (or surprising results!) otherwise.

Some fun combinations:

  • Json.encodeToString(serializer(typeOf<Int>()), Long.MAX_VALUE) == "-1"
  • Json.encodeToString(serializer(typeOf<Int>()), 3.1415) == "3"

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions