Skip to content

Commit 05702c1

Browse files
committed
fix(exec): 同步 UTF-8 输出解码修复——JDK 8 线用 decodeUtf8 helper(toString("UTF-8") + UnsupportedEncodingException 兜底,Charset 重载是 Java 10+ API)
1 parent 2e6c1a5 commit 05702c1

2 files changed

Lines changed: 37 additions & 2 deletions

File tree

‎src/main/java/io/github/easy4j/opencode/cli/OpenCodeCliExecutor.java‎

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import java.io.ByteArrayOutputStream;
1212
import java.io.File;
1313
import java.io.IOException;
14+
import java.nio.charset.StandardCharsets;
1415
import java.util.Objects;
1516

1617
/**
@@ -77,8 +78,10 @@ public OpenCodeCliResult execute(String... args) {
7778

7879
try {
7980
int exitCode = executor.execute(cmd);
80-
String out = stdout.toString().trim();
81-
String err = stderr.toString().trim();
81+
// 显式 UTF-8 解码:toString() 走平台默认字符集,GBK 默认字符集的
82+
// Windows 上会把 opencode 的 UTF-8 输出解成乱码。
83+
String out = decodeUtf8(stdout);
84+
String err = decodeUtf8(stderr);
8285
if (config.getDebug().allows(HttpLogLevel.BASIC)) {
8386
log.debug("OpenCode CLI executed: exitCode={}, stdoutLength={}, stderrLength={}",
8487
exitCode, out.length(), err.length());
@@ -92,6 +95,22 @@ public OpenCodeCliResult execute(String... args) {
9295
}
9396
}
9497

98+
/**
99+
* 按 UTF-8 解码缓冲区内容。{@code ByteArrayOutputStream.toString(Charset)}
100+
* 是 Java 10+ API,JDK 8 线退化为 {@code toString("UTF-8")};UTF-8 在所有
101+
* JVM 上保证存在,{@code UnsupportedEncodingException} 分支实际不可达。
102+
*
103+
* @param buffer 子进程输出缓冲
104+
* @return 解码后的文本
105+
*/
106+
private static String decodeUtf8(ByteArrayOutputStream buffer) {
107+
try {
108+
return buffer.toString("UTF-8");
109+
} catch (java.io.UnsupportedEncodingException e) {
110+
return buffer.toString();
111+
}
112+
}
113+
95114
/**
96115
* 探测 CLI 是否可用(执行 {@code opencode --version})。
97116
*

‎src/test/java/io/github/easy4j/opencode/cli/OpenCodeCliExecutorTest.java‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,22 @@ void shouldRejectNullConfig() {
1515
assertThrows(NullPointerException.class, () -> new OpenCodeCliExecutor(null));
1616
}
1717

18+
@Test
19+
void shouldDecodeUtf8OutputFromChildProcess() {
20+
// 子进程经 POSIX printf 八进制转义输出"你好"的 UTF-8 字节
21+
//(\344\275\240\345\245\275)。源码必须写双反斜杠:Java 字面量里
22+
// 的 \344 会被编译器当八进制转义吃掉。
23+
OpenCodeCliConfig config = new OpenCodeCliConfig();
24+
config.setExecutable("sh");
25+
config.setTimeout(5);
26+
OpenCodeCliExecutor executor = new OpenCodeCliExecutor(config);
27+
28+
OpenCodeCliResult result = executor.execute("-c", "printf '\\344\\275\\240\\345\\245\\275'");
29+
30+
assertTrue(result.isSuccess());
31+
assertEquals("你好", result.getStdout(), "UTF-8 输出必须按 UTF-8 解码,而非平台默认字符集");
32+
}
33+
1834
@Test
1935
void shouldExecuteSimpleCommand() {
2036
OpenCodeCliConfig config = new OpenCodeCliConfig();

0 commit comments

Comments
 (0)