alibaba / alibaba/fastjson2

[BUG]反序列化时,在一些情况下,有时会出现不正确的结果

Open
#7,787 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Java
Stars
4.4k
Forks
613
Avg merge
1d 22h
Merged PRs (30d)
6

Description

### 问题描述
*一个对象JSON.toJSONString()后,再parseObject()回来时,有概率出错。*
**非必现,执行十几次main方法,有可能会出现一次错误的输出。**

### 环境信息
*请填写以下信息:*

- OS信息: [e.g.:Windows11]
- JDK信息: [e.g.:Openjdk 1.8.0_202]
- 版本信息:[e.g.:Fastjson2 2.0.64]

### 重现步骤
*如何操作可以重现该问题:*

```java

//这是AjaxResult 对象
public class AjaxResult implements Serializable {

protected static final String CODE_2000 = "A-200";//成功CODE
protected static final String CODE_4000 = "A-400";//失败CODE

private static final long serialVersionUID = 1L;
private Boolean success = false;
private String msg = "操作失败!";
private String code = CODE_4000;
private Object data;

public AjaxResult() {
}

public AjaxResult(String msg) {
super();
this.setFail(msg);
}

public void setSuccess() {
this.setSuccess("操作成功!");
}

public void setFail() {
this.setFail("操作失败!");
}

public Boolean getSuccess() {
return success;
}

public void setSuccess(String msg) {
this.success = true;
this.msg = msg;
if (null == this.code || this.code.length() == 0) {
this.code = CODE_2000;
}
else if (CODE_4000.equals(this.code)) {
this.code = CODE_2000;
}
}

public void setFail(String msg) {
this.success = false;
this.msg = msg;
if (null == this.code || this.code.length() == 0) {
this.code = CODE_4000;
}
else if (CODE_2000.equals(this.code)) {
this.code = CODE_4000;
}
}

public void setSuccess(Boolean success) {
this.success = success;
}

public String getMsg() {
return msg;
}

public void setMsg(String msg) {
this.msg = msg;
}

public String getCode() {
return code;
}

public void setCode(String code) {
this.code = code;
}

public Object getData() {
return data;
}

public void setData(Object data) {
this.data = data;
}
}

//这是复现步骤
public static void main(String[] args) {

AjaxResult ajaxResult = new AjaxResult();
ajaxResult.setMsg("借方账户余额不足");
ajaxResult.setCode("4102");
ajaxResult.setSuccess(false);

String resultStr = JSON.toJSONString(ajaxResult);
System.out.println("msg1 = " + resultStr);

AjaxResult ajaxResult2 = JSON.parseObject(resultStr, AjaxResult.class);
if (ajaxResult2.getSuccess()) {
String msg = JSON.toJSONString(ajaxResult2);
System.out.println("出问题了 = " + msg);
}
}
```

### 相关日志输出
**非必现,执行十几次main方法,有可能会出现一次这样的输出:**
msg1 = {"code":"4102","msg":"借方账户余额不足","success":false}
出问题了 = {"code":"4102","msg":"false","success":true}

个人分析原因,因字段‘Boolean success; 的set方法被设计成了,导致了这样的问题。
```java
public void setSuccess(String msg) {
this.success = true;
this.msg = msg;
}

public void setSuccess(Boolean success) {
this.success = success;
}
```

Contributor guide

Open the contributing guide

Research direction

Start with the JSON.parseObject(resultStr, AjaxResult.class) call and the reported AjaxResult reproducer, then trace how deserialization chooses between the overloaded setSuccess methods. A regression test should repeat the round trip and verify that success remains false and msg remains "借方账户余额不足" rather than becoming "false".

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
64/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.