Skip to content

Commit 4d004e2

Browse files
fix(logging): keep support diagnostics truncation UTF-16 safe (#103580)
* fix(logging): keep support diagnostics truncation UTF-16 safe * docs(changelog): credit support diagnostics fix --------- Co-authored-by: Peter Steinberger <[email protected]>
1 parent e0df20b commit 4d004e2

3 files changed

Lines changed: 25 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ Docs: https://docs.openclaw.ai
4747
- **Apple timeout recovery:** return promptly from shared operation deadlines and caller cancellation even when platform work ignores cancellation, while isolating late Gateway handshakes and cleaning up location and permission waiters. (#103066) Thanks @NianJiuZst.
4848
- **Claude CLI warm sessions:** preserve managed stdio continuity when Claude writes no native transcript, fall back to bounded OpenClaw history only when the exact live child disappears or changes, and keep stateless runs from persisting CLI bindings. (#96841) Thanks @bradreaves.
4949
- **CLI plugin listing:** skip state-migration runtime loading when no legacy inputs exist, reducing packaged cold-start memory while preserving migrations for legacy plugin indexes and configured session stores.
50-
- **Unicode-safe bounded text:** preserve complete UTF-16 surrogate pairs when shortening previews, prompts, diagnostics, labels, session keys, link metadata, and identity values across Control UI, CLI, Gateway, plugins, QA, memory, and Android surfaces. (#102625, #102626, #102627, #102656, #102816, #102823, #102833, #102877, #102949, #102963, #102969, #102988, #103010, #103034, #103210, #103341, #103487, #103543) Thanks @zhangguiping-xydt, @wings1029, @wangyan2026, @Pandah97, @MoerAI, @SunnyShu0925, @zhangqueping, @zw-xysk, @cxbAsDev, @lzyyzznl, @coder-master-0915, @LeonidasLux, @mushuiyu886, @ly85206559, @Simon-XYDT, and @lsr911.
50+
- **Unicode-safe bounded text:** preserve complete UTF-16 surrogate pairs when shortening previews, prompts, diagnostics, labels, session keys, link metadata, and identity values across Control UI, CLI, Gateway, plugins, QA, memory, and Android surfaces. (#102625, #102626, #102627, #102656, #102816, #102823, #102833, #102877, #102949, #102963, #102969, #102988, #103010, #103034, #103210, #103341, #103487, #103543, #103580) Thanks @zhangguiping-xydt, @wings1029, @wangyan2026, @Pandah97, @MoerAI, @SunnyShu0925, @zhangqueping, @zw-xysk, @cxbAsDev, @lzyyzznl, @coder-master-0915, @LeonidasLux, @mushuiyu886, @ly85206559, @Simon-XYDT, and @lsr911.
5151
- **CLI model tables:** sanitize, truncate, and pad model-list cells by rendered terminal width so emoji, CJK, and other wide graphemes keep columns aligned. (#102819) Thanks @Kevin23-design and @vincentkoc.
5252
- **Skills prompt compaction:** preserve every included skill identity before using the remaining prompt budget for shortened, UTF-16-safe descriptions, retaining trigger guidance without exceeding the hard limit. (#88426) Thanks @abel-zer0.
5353
- **Channel Markdown code tables:** size columns by rendered display width so CJK, emoji, and mixed-width cells stay aligned across shared Telegram and Discord output. (#55596, #55512) Thanks @sparkyrider.

src/logging/diagnostic-support-export.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,28 @@ describe("diagnostic support export", () => {
728728
}
729729
});
730730

731+
it("truncates support strings without splitting UTF-16 surrogate pairs", () => {
732+
const redaction = {
733+
env: {
734+
HOME: tempDir,
735+
OPENCLAW_STATE_DIR: tempDir,
736+
},
737+
stateDir: tempDir,
738+
};
739+
const truncationSuffix = "...<truncated>";
740+
741+
expect(redactSupportString("abcd😀tail", redaction, { maxLength: 5 })).toBe(
742+
`abcd${truncationSuffix}`,
743+
);
744+
745+
const redactedPathPrefix = `$OPENCLAW_STATE_DIR${path.sep}`;
746+
expect(
747+
redactSupportString(path.join(tempDir, "abcd😀tail"), redaction, {
748+
maxLength: redactedPathPrefix.length + 5,
749+
}),
750+
).toBe(`${redactedPathPrefix}abcd${truncationSuffix}`);
751+
});
752+
731753
it("redacts Windows USERPROFILE paths when HOME is unset", () => {
732754
const userProfile = "C:\\Users\\support-user";
733755
const stateDir = `${userProfile}\\AppData\\Roaming\\openclaw`;

src/logging/diagnostic-support-redaction.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import path from "node:path";
33
import { isSensitiveUrlQueryParamName } from "@openclaw/net-policy/redact-sensitive-url";
44
import { asOptionalRecord } from "@openclaw/normalization-core/record-coerce";
5+
import { truncateUtf16Safe } from "@openclaw/normalization-core/utf16-slice";
56
import { REDACTED_SENTINEL } from "../config/redact-snapshot.js";
67
import { isSecretRefShape } from "../config/redact-snapshot.secret-ref.js";
78
import { isBlockedObjectKey } from "../infra/prototype-keys.js";
@@ -344,7 +345,7 @@ export function redactSupportString(
344345
if (pathRedacted.length <= maxLength) {
345346
return pathRedacted;
346347
}
347-
return `${pathRedacted.slice(0, maxLength)}${truncationSuffix}`;
348+
return `${truncateUtf16Safe(pathRedacted, maxLength)}${truncationSuffix}`;
348349
}
349350

350351
function sanitizeCommandArguments(args: unknown[], redaction: SupportRedactionContext): unknown[] {

0 commit comments

Comments
 (0)