FastJson中一些较少提到的特性
都是23年11月左右自己看源码+调试测出来的特性,结果后来发现早两年就有人研究过Constructor的调用逻辑了((((((
添加白名单绕过特性应该也挺早就被前人发现过,最终在22年下旬造成了最近的一次绕过
调用Constructor机制
低版本
目标类必须有**默认方法
,FastJson反序列化时也只会调用default-constructor
**
没有就报错,此时都没有缓存机制
高版本
开了AutoType后,利用缓存机制多打几次就可以打破默认构造方法的必要性限制
这样就能调用无参以外的构造方法了
然而有好几个限制点:
如果目标类有默认构造方法,就不会调用有参构造方法
如果调用有参构造方法,就不会在反序列化阶段调用任何setter与getter
与Jackson不同,在FastJson中通过**
传String类型的参数
来调用对应setter
, 不能自动做类型转换而调用setter的参数类** 的**String类型的构造方法
**(这本来也不该能调用,我实在不知道为什么Jackson支持)那么调用目标的什么构造方法呢?参照第一点,FastJson仍然会优先调用默认构造方法创建对象,并调用setter、getter,都不行就反射修改public属性来赋值
如果类压根没有这个属性(父类私有) 就去往上找父类,找到第一个有这个属性的父类就开始调用setter/getter/… 最终会赋给子类就离谱()
顺序
按照
getConstructors()
获取到的顺序,取第一位调用,这个过程甚至可能随机: https://zhuanlan.zhihu.com/p/535423876顺序不受Json数据影响,假如有AB两个构造方法,其中A的参数是A1、A2,B的参数是B1、B2;传A1A2,如果B的顺序更先,它宁愿给B1B2初始化默认值,也不会调用A方法
总结
相比于Jackson、Snakeyaml
FastJson:
很难调用到想要的有参Constructor
若有一个不会被拦截的类,其中具有setXxxxx….(Classpath….)方法,且拥有Default-Constructor(如果用缓存绕过默认限制,会导致走不到借助settter实现的绕过逻辑),则Classpath…..可以蹭车通过checkAutoType ——从而调用到对应的setter,不能调getter,但可以调指定有参构造方法,但也别忘了————
如果调用的是有参构造方法,就不会在反序列化阶段调用任何setter与getter
第二点在[新思路](1.2.68 & 1.2.80新思路.md)里有更详细的说明,具体可用于添加白名单缓存
- 本文链接:https://whocansee.github.io/2024/03/21/FastJson%E4%B8%AD%E8%BE%83%E5%B0%91%E6%8F%90%E5%88%B0%E7%9A%84%E7%89%B9%E6%80%A7/
- 版权声明:本博客所有文章除特别声明外,均默认采用 许可协议。