Skip to content

Commit 3687fcb

Browse files
committed
fix(exec)+test: 子进程输出显式 UTF-8 解码回归测试;argv 原样传参修复多词参数被字面引号损坏
- 回归测试:/bin/sh -c printf 八进制转义输出「你好」UTF-8 字节,断言 执行器以 UTF-8 解码正确(Java 源码 \344 须双写为 \\344,否则编译期被 八进制转义消费) - 修复 toCommandLine:commons-exec addArgument 默认 handleQuoting=true 会把含空格参数包进字面双引号存入 argv,sh -c 收到后把整段脚本当成 单个命令名(exit=127);改 addArgument(arg, false) 原样传参, openclaw message 等多词参数命令由此修复 - 解码路径本身已是显式 UTF-8(new String(toByteArray(), UTF_8)),无需改动
1 parent 53c25da commit 3687fcb

2 files changed

Lines changed: 52 additions & 1 deletion

File tree

‎src/main/java/io/github/easy4j/openclaw/cli/OpenClawCliExecutor.java‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,10 @@ public CommandLine toCommandLine(OpenClawCliRequest request) {
155155
cmd.addArgument("--no-color");
156156
}
157157
for (String a : request.getArguments()) {
158-
cmd.addArgument(a);
158+
// handleQuoting=false:子进程经 exec(argv) 启动而非 shell,多词参数
159+
// 不需要引号包裹;commons-exec 默认引号会成为 argv 的字面字符,
160+
// 导致 sh -c 把整段脚本当成单个命令名。
161+
cmd.addArgument(a, false);
159162
}
160163
return cmd;
161164
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright (c) 2018-present, easy-4-java (https://github.com/easy-4-java).
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.github.easy4j.openclaw.cli;
17+
18+
import io.github.easy4j.openclaw.OpenClawCliConfig;
19+
import org.junit.jupiter.api.Test;
20+
21+
import static org.junit.jupiter.api.Assertions.assertEquals;
22+
23+
/**
24+
* CLI 子进程输出的字符集解码回归测试:执行器必须以 UTF-8 显式解码子进程输出,
25+
* 而不是依赖平台默认字符集(C locale / GBK 环境下中文与 Emoji 会损坏)。
26+
*
27+
* <p>子进程用 POSIX printf 的八进制转义({@code \344\275\240\345\245\275})输出
28+
* “你好”的原始 UTF-8 字节。注意:Java 源码里的反斜杠必须双写,否则
29+
* {@code \344} 会在编译期被当作八进制转义吃掉。</p>
30+
*
31+
* @since 1.0.0
32+
*/
33+
class OpenClawCliExecutorUtf8DecodeTest {
34+
35+
@Test
36+
void shouldDecodeUtf8OutputRegardlessOfPlatformCharset() {
37+
OpenClawCliConfig config = new OpenClawCliConfig();
38+
config.setExecutable("/bin/sh");
39+
config.setTimeout(10);
40+
OpenClawCliExecutor executor = new OpenClawCliExecutor(config);
41+
42+
OpenClawCliResult result = executor.execute(OpenClawCliRequest.builder()
43+
.arguments("-c", "printf '\\344\\275\\240\\345\\245\\275'")
44+
.build());
45+
46+
assertEquals("你好", result.getStdout());
47+
}
48+
}

0 commit comments

Comments
 (0)