Skip to content

Commit f1c2ff1

Browse files
committed
deps(2.0): migrate fastjson to 2.0.x v1-compat build — resolve CVE-2026-16723
rythm-engine 硬编码 com.alibaba.fastjson v1 API(JSONWrapper / TemplateBase / S), 无 JSON 抽象层或 SPI,无法以 jackson 或直接 exclusion 替换(exclusion 会砍掉 rythm 的 JSON 渲染参数便利路径且上游仍强引用)。 采用 alibaba 官方过渡方案:com.alibaba:fastjson:2.0.57 —— 同一 GAV、v1 包名与 API 面(JSON.parse/parseArray/parseObject、JSONArray 实现 java.util.List), 内部实现为 fastjson2 内核,彻底脱离已终止维护且存在无修复 RCE 的 1.2.x 线。 - 根 pom 新增 dependencyManagement 锁定($fastjson.version=2.0.57) - 新增 RythmFastjsonCompatTest 锁定 rythm 实际调用的 v1 API 面: JSONWrapper 构造/getObject/getArray/isArray、typed parseObject/parseArray、 JSONArray size()/get(int)/toString() 循环模式 —— 兼容面回归可观测
1 parent da5a424 commit f1c2ff1

2 files changed

Lines changed: 94 additions & 0 deletions

File tree

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package io.github.easy4j.doc.rythm;
2+
3+
import com.alibaba.fastjson.JSON;
4+
import com.alibaba.fastjson.JSONArray;
5+
import com.alibaba.fastjson.JSONObject;
6+
import org.junit.jupiter.api.DisplayName;
7+
import org.junit.jupiter.api.Test;
8+
import org.rythmengine.utils.JSONWrapper;
9+
10+
import java.util.List;
11+
import java.util.Map;
12+
13+
import static org.junit.jupiter.api.Assertions.assertEquals;
14+
import static org.junit.jupiter.api.Assertions.assertFalse;
15+
import static org.junit.jupiter.api.Assertions.assertTrue;
16+
17+
/**
18+
* rythm-engine 传递依赖 fastjson 的兼容性冒烟测试。
19+
*
20+
* <p>背景:rythm 在 {@code utils/JSONWrapper}、{@code template/TemplateBase}、
21+
* {@code utils/S} 中硬编码 fastjson <b>v1</b> API(com.alibaba.fastjson.*),且无 JSON 抽象层/SPI。
22+
* 1.2.x 线已终止维护并存在无修复的 CVE-2026-16723(影响 1.2.68–1.2.83),
23+
* 因此本工程将 effective 版本锁定到 <b>2.0.x v1 兼容构建</b>——同一 GAV,
24+
* 包名与 API 面保持 v1,内部实现切换为 fastjson2 内核。</p>
25+
*
26+
* <p>本测试锁定 rythm 实际调用的那部分 v1 API 面,防止未来误把依赖降回 1.2.x
27+
* 或升级到破坏 v1 兼容面的版本时无人察觉:</p>
28+
* <ul>
29+
* <li>{@code JSON.parse(String)} —— JSONWrapper 构造路径</li>
30+
* <li>{@code JSON.parseArray(String, Class)} / {@code JSON.parseObject(String, Class)}
31+
* —— TemplateBase.__setRenderArg(JSONWrapper) 的带类型参数绑定路径</li>
32+
* <li>JSONArray 的 {@code size()/get(int)/toString()} —— TemplateBase.setJSONArray/setJSONObject</li>
33+
* <li>{@code JSONWrapper#isArray()/getArray()/getObject()} —— rythm 自身类在兼容构建下的行为</li>
34+
* </ul>
35+
*/
36+
class RythmFastjsonCompatTest {
37+
38+
@Test
39+
@DisplayName("JSON.parse — JSONWrapper 构造 + 对象访问路径")
40+
void jsonParseViaJsonWrapper() {
41+
JSONWrapper wrapper = new JSONWrapper("{\"name\":\"张三\",\"age\":30}");
42+
assertFalse(wrapper.isArray());
43+
Map<String, Object> obj = wrapper.getObject();
44+
assertEquals("张三", obj.get("name"));
45+
assertEquals(30, obj.get("age"));
46+
}
47+
48+
@Test
49+
@DisplayName("JSONWrapper 数组路径 — isArray/getArray")
50+
void jsonWrapperArrayPath() {
51+
JSONWrapper wrapper = new JSONWrapper("[{\"id\":1},{\"id\":2}]");
52+
assertTrue(wrapper.isArray());
53+
List<Object> list = wrapper.getArray();
54+
assertEquals(2, list.size());
55+
}
56+
57+
@Test
58+
@DisplayName("JSON.parseObject/parseArray 带类型绑定 — TemplateBase 渲染参数路径")
59+
void typedBindingSurface() {
60+
JSONObject obj = JSON.parseObject("{\"title\":\"t\",\"n\":2}", JSONObject.class);
61+
assertEquals("t", obj.getString("title"));
62+
assertEquals(2, obj.getIntValue("n"));
63+
64+
List<String> arr = JSON.parseArray("[\"a\",\"b\"]", String.class);
65+
assertEquals(2, arr.size());
66+
assertEquals("b", arr.get(1));
67+
}
68+
69+
@Test
70+
@DisplayName("对象→数组元素逐个 parseObject — setJSONObject 循环模式(含 size/get/toString)")
71+
void elementWiseParse() {
72+
String arrayStr = "[{\"k\":\"v1\"},{\"k\":\"v2\"}]";
73+
JSONArray raw = (JSONArray) JSON.parse(arrayStr);
74+
assertEquals(2, raw.size());
75+
for (int i = 0; i < raw.size(); i++) {
76+
Object el = raw.get(i);
77+
JSONObject parsed = JSON.parseObject(el.toString(), JSONObject.class);
78+
assertEquals("v" + (i + 1), parsed.getString("k"));
79+
}
80+
}
81+
}

‎pom.xml‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@
4949
<java.version>17</java.version>
5050
<maven.compiler.release>${java.version}</maven.compiler.release>
5151
<maven.version>3.9.16</maven.version>
52+
53+
<!-- fastjson:v1 兼容构建(内核 fastjson2),锁定 rythm-engine 传递依赖 -->
54+
<fastjson.version>2.0.57</fastjson.version>
5255
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
5356

5457
<!-- ═══ Docx4j 全家桶版本(11.5.14 统一锁定) ═══ -->
@@ -792,6 +795,16 @@
792795
<scope>import</scope>
793796
</dependency>
794797

798+
<!-- fastjson 2.x(v1 兼容构建,内核为 fastjson2):锁定 rythm-engine 传递依赖。
799+
1.2.x 线已终止且存在无修复的 CVE-2026-16723(RCE 家族);
800+
2.0.x 保持 com.alibaba.fastjson v1 包名与 API(rythm 硬编码依赖),
801+
内部实现切换到 fastjson2 内核,彻底脱离受影响的 1.2.x 线 -->
802+
<dependency>
803+
<groupId>com.alibaba</groupId>
804+
<artifactId>fastjson</artifactId>
805+
<version>${fastjson.version}</version>
806+
</dependency>
807+
795808
<!-- ======== Test ======== -->
796809

797810
<!-- https://mvnrepository.com/artifact/junit/junit -->

0 commit comments

Comments
 (0)