alibaba / alibaba/fastjson2

[BUG]BigDecimal 0E+15,JSON序列化时,出现数组越界

Open
#3,950 2 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

### 问题描述
map的值,存在0E+15这种BigDecimal值,概率出现数组越界异常。

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

- OS信息: [e.g.:CentOS 8.4.2105 4Core 3.10GHz 16 GB]
- JDK信息: [e.g.:Openjdk 1.8.0_312]
- 版本信息:[e.g.:Fastjson2 2.0.44]

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

```java
double b = 2d / 3d;
BigDecimal v1 = new BigDecimal("0").setScale(-15);
String vs = v1.toPlainString();
BigDecimal v = new BigDecimal("000").divide(new BigDecimal("3"));

JSONObject m = new JSONObject();
m.put("a", v);
m.put("a1", b);
m.put("a2", v1);
m.put("a3", vs);
Random r = new Random();
for (int i = 0;i< 10000;i++) {
m.put(r.nextInt(100000)+"a"+i, v1);
}
SerializeConfig serializeConfig = new SerializeConfig(SerializeConfig.DEFAULT_PROVIDER);

String str = JSON.toJSONString((Object) m, serializeConfig, SerializerFeature.WriteBigDecimalAsPlain, SerializerFeature.DisableCircularReferenceDetect);

```

### 期待的正确结果
能够序列化成0

### 相关日志输出
java.lang.StringIndexOutOfBoundsException: offset 41472, count 1, length 41472

at java.base/java.lang.String.checkBoundsOffCount(String.java:4591)
at java.base/java.lang.String.getChars(String.java:1679)
at com.alibaba.fastjson2.JSONWriterUTF16.writeDecimal(JSONWriterUTF16.java:1309)
at com.alibaba.fastjson2.writer.ObjectWriterImplMap.write(ObjectWriterImplMap.java:507)
at com.alibaba.fastjson2.JSONWriter.writeAny(JSONWriter.java:1420)
at com.alibaba.fastjson.JSON.toJSONString(JSON.java:1690)

#### 附加信息
问题原因
com.alibaba.fastjson2.JSONWriterUTF16#writeDecimal
Image
scale = -15,导致后面的ensureCapacity未扩容,正好off == chars.length。最终chars插入0时出现数组越界

Contributor guide

Open the contributing guide

Research direction

Start in JSONWriterUTF16.writeDecimal, using the supplied BigDecimal scale=-15 reproduction and stack trace to inspect capacity handling before writing 0. Run the provided serialization example with WriteBigDecimalAsPlain and confirm the map serializes successfully as 0 without StringIndexOutOfBoundsException.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
backend-api-design
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.