Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] BigDecimal 0e-7序列化时候会有bug #2076

Closed
liuze0118 opened this issue Dec 5, 2023 · 6 comments
Closed

[BUG] BigDecimal 0e-7序列化时候会有bug #2076

liuze0118 opened this issue Dec 5, 2023 · 6 comments
Labels
bug Something isn't working fixed
Milestone

Comments

@liuze0118
Copy link

问题描述

简要描述您碰到的问题。
调用 JSONObject.toJSONString(jsonObject); 当对象中有bigdecimal = 0e-7 字段时候,IOUtil 在 writeDecimal时候如果off = buffer.size 不会进行扩容,会报数组下标越界
java.lang.ArrayIndexOutOfBoundsException: Index 314928 out of bounds for length 8192
at com.alibaba.fastjson2.util.IOUtils.writeInt64(IOUtils.java:1085)
at com.alibaba.fastjson2.util.IOUtils.writeDecimal(IOUtils.java:381)
at com.alibaba.fastjson2.JSONWriterUTF16.writeDecimal(JSONWriterUTF16.java:1305)
at com.alibaba.fastjson2.writer.ObjectWriterImplMap.write(ObjectWriterImplMap.java:497)
at com.alibaba.fastjson2.writer.ObjectWriterImplMap.write(ObjectWriterImplMap.java:548)
at com.alibaba.fastjson2.JSON.toJSONString(JSON.java:2815)
at com.alibaba.fastjson2.JSONObject.toJSONString(JSONObject.java:1144)

环境信息

请填写以下信息:

  • 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.40]

重现步骤

如何操作可以重现该问题:
public static void main(String[] args) throws IOException {
String str = String.valueOf(FileUtil.readChars(new File("C:\***\SO1231205000018.txt")));
JSONObject.toJSONString(str);
JSONObject jsonObject = JSONObject.parseObject(str);
JSONObject.toJSONString(jsonObject);
}
image
等于的时候没有扩容 导致后续数组下标越界

期待的正确结果

对您期望发生的结果进行清晰简洁的描述。

相关日志输出

请复制并粘贴任何相关的日志输出。
java.lang.ArrayIndexOutOfBoundsException: Index 314928 out of bounds for length 8192
at com.alibaba.fastjson2.util.IOUtils.writeInt64(IOUtils.java:1085)
at com.alibaba.fastjson2.util.IOUtils.writeDecimal(IOUtils.java:381)
at com.alibaba.fastjson2.JSONWriterUTF16.writeDecimal(JSONWriterUTF16.java:1305)
at com.alibaba.fastjson2.writer.ObjectWriterImplMap.write(ObjectWriterImplMap.java:497)
at com.alibaba.fastjson2.writer.ObjectWriterImplMap.write(ObjectWriterImplMap.java:548)
at com.alibaba.fastjson2.JSON.toJSONString(JSON.java:2815)
at com.alibaba.fastjson2.JSONObject.toJSONString(JSONObject.java:1144)

附加信息

如果你还有其他需要提供的信息,可以在这里填写(可以提供截图、视频等)。
json文件在附件
SO1231205000018.txt

@liuze0118 liuze0118 added the bug Something isn't working label Dec 5, 2023
@liuze0118
Copy link
Author

报错信息写错了,是这个:
java.lang.ArrayIndexOutOfBoundsException: Index 314928 out of bounds for length 314928
at com.alibaba.fastjson2.util.IOUtils.writeInt64(IOUtils.java:1085)
at com.alibaba.fastjson2.util.IOUtils.writeDecimal(IOUtils.java:381)
at com.alibaba.fastjson2.JSONWriterUTF16.writeDecimal(JSONWriterUTF16.java:1305)
at com.alibaba.fastjson2.writer.ObjectWriterImplMap.write(ObjectWriterImplMap.java:497)
at com.alibaba.fastjson2.writer.ObjectWriterImplList.write(ObjectWriterImplList.java:366)
at com.alibaba.fastjson2.writer.ObjectWriterImplMap.write(ObjectWriterImplMap.java:548)
at com.alibaba.fastjson2.writer.ObjectWriterImplList.write(ObjectWriterImplList.java:366)
at com.alibaba.fastjson2.writer.ObjectWriterImplMap.write(ObjectWriterImplMap.java:548)
at com.alibaba.fastjson2.JSON.toJSONString(JSON.java:2815)
at com.alibaba.fastjson2.JSONObject.toJSONString(JSONObject.java:1144)
at com.sch.order.application.service.impl.SplitOrderServiceImpl.main(SplitOrderServiceImpl.java:412)
image

@wenshao
Copy link
Member

wenshao commented Dec 6, 2023

https://oss.sonatype.org/content/repositories/snapshots/com/alibaba/fastjson2/fastjson2/2.0.44-SNAPSHOT/
问题重现并且修复,请帮忙用2.0.44-SNAPSHOT版本验证,2.0.44版本预计在2024年元旦发布

@wenshao wenshao added this to the 2.0.44 milestone Dec 6, 2023
@wenshao wenshao added the fixed label Dec 6, 2023
@liuze0118
Copy link
Author

image
问题确实修改了,但是如图所示。 标记1. 当前bigdecimal是 0e-7 字符长度是9 位。 标记3 -标记 2 是偏移 长度 626-611 = 15 位 ,所以这种修改方式感觉不够精确
image
上图是2.0.6版本的处理方式,直接使用了bigdecimal的字符串长度来做偏移,感觉这种处理方式更优雅

@liuze0118
Copy link
Author

image
这个问题的核心点是 获取bigdecimal 小数点前的有效位数的问题。 如果 1.00 结果 是 2位。 11.00 结果是 3位 但是如果小数点前的首位是0的时候 比如 0.00 结果就是 1 也就是说bigdecimal的 precision方法会舍掉小数点前面的首位的0 ,有效位数就只有小数点了变成 1位 。这样偏移计算的时候就会少一位,所以补完小数点后的0之后,再写小说点前的值的时候,以为少偏移了一位,就会在临界情况导致数组小标越界。

@wenshao
Copy link
Member

wenshao commented Dec 6, 2023

2.0.6版本的实现性能较差,当前的实现不够精确,可以继续改进。

@wenshao
Copy link
Member

wenshao commented Dec 24, 2023

@wenshao wenshao closed this as completed Dec 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working fixed
Projects
None yet
Development

No branches or pull requests

2 participants