Skip to content

[BUG] 序列化及反序列化 kotlin 的 value class 的逻辑存在严重漏洞 #3288

@EmptyDreams

Description

@EmptyDreams

问题描述

当一个类中包含了一个 value class 时,fastjson2 序列化为 json 的时候会给这个字段添加一个固定的后缀,即使我通过 JSONField 手动指定名称,仍然会携带该后缀,这样子序列化出来的 json 不方便其它地方解析。

在 fastjson2 解序列化时,却不会添加这个后缀,这导致 fastjson2 无法解序列化自己序列化的 json,这非常的不合理。

更严重的问题是,当 value class 内部是一个基础类型时,fastjson2 永远将 value class 当做基础类型处理,所以在反序列化遇到装箱时就会出现类似的错误:

Caused by: java.lang.IllegalArgumentException: argument type mismatch
	at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:65)
	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
	... 32 common frames omitted
Caused by: java.lang.ClassCastException: Cannot cast java.lang.Integer to kotlin.jvm.internal.DefaultConstructorMarker
	at java.base/java.lang.Class.cast(Class.java:4067)
	at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
	... 35 common frames omitted

环境信息

  • OS信息: macOS 15.1.1 (24B91) 2.6 GHz 六核Intel Core i7
  • JDK信息: graalvm 21.0.5
  • 版本信息:2.0.53

重现步骤

编写如下代码:

@JvmInline
value class Test(val a: Int)

data class Test2(
//    @JSONField(name = "b")
    val b: Test
)

fun main() {
    println(Test(1).toJSONString())
    println(JSON.parseObject("{\"a\":1}", Test::class.java))
    println(Test2(Test(1)).toJSONString())
    println(JSON.parseObject("{\"b-C9M8Yyk\":2}", Test2::class.java))
    println(JSON.parseObject("{\"b\":2}", Test2::class.java))
}

最终得到如下输出:

{"a":1}
Test(a=1)
{"b-C9M8Yyk":1}        // 取消掉 JSONField 的注释后结果仍为这样
Test2(b=Test(a=0))    // 这两行的结果应该和序列化的行为保持一致,而不是两边使用两个命名规则
Test2(b=Test(a=2))

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfixed

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions