Skip to content

fix(qqbot): use truncateUtf16Safe for debug log URL/key truncation#102572

Merged
steipete merged 2 commits into
openclaw:mainfrom
lsr911:fix/utf16-qqbot
Jul 9, 2026
Merged

fix(qqbot): use truncateUtf16Safe for debug log URL/key truncation#102572
steipete merged 2 commits into
openclaw:mainfrom
lsr911:fix/utf16-qqbot

Conversation

@lsr911

@lsr911 lsr911 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

QQBot emits bounded debug previews for probed image URLs and upload-cache keys. Those local 60- and 40-code-unit caps used slice, so a surrogate pair crossing either boundary could leave malformed UTF-16 before the shared debug logger applied its larger global cap.

Why This Change Was Made

Use the existing truncateUtf16Safe utility at each small, context-specific preview boundary. The URL and cache-key limits, ellipses, cache semantics, network behavior, and global debug sanitization remain unchanged.

The follow-up tests exercise every changed call site: successful and failed image probes assert exact URL previews, while real cache set/hit calls assert exact key previews with a target identifier whose emoji straddles the cache-key boundary.

User Impact

Opt-in QQBot debug logs remain bounded but no longer contain malformed Unicode at these preview limits. Image probing, media upload caching, API routes, and configuration are unchanged.

Evidence

  • node ../../node_modules/vitest/vitest.mjs run --config test/vitest/vitest.extension-messaging.config.ts extensions/qqbot/src/engine/utils/image-size.test.ts extensions/qqbot/src/engine/utils/upload-cache.test.ts — 2 files and 17 tests passed.
  • oxfmt completed on all changed files.
  • git diff --check passed.
  • Source review covered image probe callers, direct and chunked upload-cache callers, QQBot debug sanitization, key construction, scope types, and existing SSRF/cache tests.

Risk

Low. Four internal debug-preview expressions now share the established UTF-16 truncation invariant; runtime API and cache behavior are unaffected.

AI-assisted

This PR was generated with Claude Code and improved/reviewed by a maintainer agent.

Replace naive .slice(0, N) with truncateUtf16Safe() in:
- image-size.ts: URL preview in debug logs (2 sites)
- upload-cache.ts: cache key preview in debug logs (2 sites)

Co-Authored-By: Claude <[email protected]>
@openclaw-barnacle openclaw-barnacle Bot added channel: qqbot size: XS triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. labels Jul 9, 2026
@clawsweeper

clawsweeper Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 9, 2026, 6:17 AM ET / 10:17 UTC.

Summary
The PR replaces four QQBot debug-log URL/cache-key .slice previews with truncateUtf16Safe and adds focused tests for the changed call sites.

PR surface: Source +6, Tests +54. Total +60 across 4 files.

Reproducibility: yes. from source inspection: current main uses raw .slice for the QQBot URL and cache-key preview caps, so a surrogate pair crossing those exact caps can produce malformed UTF-16 in opt-in debug logs. I did not execute a real QQBot run, so this is source-reproducible rather than runtime-reproduced.

Review metrics: none identified.

Stored data model
Persistent data-model change detected: persistent cache schema: extensions/qqbot/src/engine/utils/upload-cache.test.ts, persistent cache schema: extensions/qqbot/src/engine/utils/upload-cache.ts. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Overall: 🦪 silver shellfish
Proof: 🧂 unranked krab
Patch quality: 🦞 diamond lobster
Result: blocked until real behavior proof from a real setup is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Add redacted real behavior proof showing a QQBot debug log for a long URL or cache key with emoji/surrogate-pair text after the change.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR body provides unit-test and static-check evidence only; before merge, the contributor should add a redacted QQBot debug-log transcript, terminal output, or comparable live run showing safe truncation, then update the PR body to trigger re-review.

Risk before merge

  • [P1] The contributor has not provided real after-fix QQBot/logging proof, so merge readiness still rests on source inspection and unit tests rather than an observed QQBot debug-log path.

Maintainer options:

  1. Decide the mitigation before merge
    Land the narrow SDK-helper substitution after a redacted QQBot debug-log transcript or terminal run shows a long URL or cache key with surrogate-pair text truncating cleanly.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P1] Not a repair-lane candidate: the code change is already present and the remaining blocker is contributor-supplied real behavior proof, not an automated code repair.

Security
Cleared: The diff only uses an existing SDK text helper and adds tests; it does not add code execution, dependencies, secret handling, permissions, CI, or supply-chain surface.

Review details

Best possible solution:

Land the narrow SDK-helper substitution after a redacted QQBot debug-log transcript or terminal run shows a long URL or cache key with surrogate-pair text truncating cleanly.

Do we have a high-confidence way to reproduce the issue?

Yes from source inspection: current main uses raw .slice for the QQBot URL and cache-key preview caps, so a surrogate pair crossing those exact caps can produce malformed UTF-16 in opt-in debug logs. I did not execute a real QQBot run, so this is source-reproducible rather than runtime-reproduced.

Is this the best way to solve the issue?

Yes, this is the narrow maintainable fix: QQBot already uses the supported plugin SDK truncateUtf16Safe helper on sibling debug surfaces, and the PR preserves caps, ellipses, cache semantics, and network behavior. The remaining gap is proof, not code shape.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against e39e628a8416.

Label changes

Label justifications:

  • P3: This is a low-risk QQBot debug-log formatting cleanup with limited user impact and no evidence of a broken channel workflow.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🧂 unranked krab and patch quality is 🦞 diamond lobster.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body provides unit-test and static-check evidence only; before merge, the contributor should add a redacted QQBot debug-log transcript, terminal output, or comparable live run showing safe truncation, then update the PR body to trigger re-review.
Evidence reviewed

PR surface:

Source +6, Tests +54. Total +60 across 4 files.

View PR surface stats
Area Files Added Removed Net
Source 2 10 4 +6
Tests 2 54 0 +54
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 4 64 4 +60

What I checked:

Likely related people:

  • MonkeyLeeT: In this shallow checkout, git blame attributes the current QQBot utility lines around both raw truncations to merge commit f984209; live PR metadata maps the source PR author for that merge to MonkeyLeeT. (role: current-main blamed code author; confidence: low; commits: f984209f54d5; files: extensions/qqbot/src/engine/utils/image-size.ts, extensions/qqbot/src/engine/utils/upload-cache.ts)
  • steipete: Live metadata shows steipete merged the current-main blame PR, and this PR's latest commit adding focused QQBot tests is also authored by steipete. (role: recent merger and adjacent contributor; confidence: medium; commits: f984209f54d5, 0a1b869a2a64; files: extensions/qqbot/src/engine/utils/image-size.test.ts, extensions/qqbot/src/engine/utils/upload-cache.test.ts)
  • Vincent Koc: The shallow history shows release commit e085fa1 as the prior baseline that contained the normalization helper and QQBot files before later main commits; this is weak routing evidence only. (role: release-baseline contributor; confidence: low; commits: e085fa1a3ffd; files: packages/normalization-core/src/utf16-slice.ts, src/plugin-sdk/text-utility-runtime.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (1 earlier review cycle)
  • reviewed 2026-07-09T09:08:52.615Z sha c623973 :: needs real behavior proof before merge. :: none

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. labels Jul 9, 2026
@openclaw-barnacle openclaw-barnacle Bot added size: S and removed size: XS triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. labels Jul 9, 2026
@steipete

steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Land-ready proof for exact head 0a1b869a2a64cbf96c2e5937aff892fe0a73c0ed:

  • Reviewed all four QQBot debug-preview boundaries: image-size success/failure URLs and upload-cache set/hit keys now share the UTF-16-safe truncation helper.
  • Added exact regression coverage with an emoji straddling each boundary; image-size.test.ts and upload-cache.test.ts pass (17 tests).
  • oxfmt, git diff --check, and a fresh branch autoreview pass clean with no actionable findings.
  • Native OPENCLAW_TESTBOX=1 scripts/pr prepare-run 102572 accepted exact-head hosted CI/Testbox. The current exact-head proof runs pass; the older failed/cancelled proof records are superseded.

No changelog entry is required because this only sanitizes diagnostic preview boundaries. No known proof gaps.

@steipete
steipete merged commit 1beea4b into openclaw:main Jul 9, 2026
105 of 109 checks passed
@steipete

steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 10, 2026
…penclaw#102572)

* fix(qqbot): use truncateUtf16Safe for debug log URL/key truncation

Replace naive .slice(0, N) with truncateUtf16Safe() in:
- image-size.ts: URL preview in debug logs (2 sites)
- upload-cache.ts: cache key preview in debug logs (2 sites)

Co-Authored-By: Claude <[email protected]>

* test(qqbot): cover UTF-16-safe debug previews

---------

Co-authored-by: Claude <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: qqbot P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. size: S status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants