Skip to content

fix(feishu): recover CJK filenames from JSON file_name field (fixes #81103)#93772

Merged
vincentkoc merged 2 commits into
openclaw:mainfrom
liuhao1024:fix/feishu-cjk-json-filename-v2
Jun 16, 2026
Merged

fix(feishu): recover CJK filenames from JSON file_name field (fixes #81103)#93772
vincentkoc merged 2 commits into
openclaw:mainfrom
liuhao1024:fix/feishu-cjk-json-filename-v2

Conversation

@liuhao1024

Copy link
Copy Markdown
Contributor

Problem

CJK filenames in inbound Feishu messages produce mojibake when the filename is delivered via the JSON file_name field. The recoverUtf8FileNameFromLatin1Header helper is already called for Content-Disposition headers (decodeDispositionFileName at extensions/feishu/src/media.ts:212) but not for the JSON fallback path in extractFeishuDownloadMetadata.

This means 武汉15座山登山信息汇总.csv lands on disk as æ­¦æ±15座山ç»å±±ä¿¡æ¯æ±æ»¥.csv when the Feishu API returns the filename in the JSON body.

The existing test at line 902 ("keeps JSON-derived file_name metadata unchanged") actively asserted this broken behavior.

Fix

Apply recoverUtf8FileNameFromLatin1Header to the JSON-derived filename in extractFeishuDownloadMetadata, so CJK filenames are recovered regardless of which path carries the name. The helper is safe for non-Latin-1 values (returns input unchanged when recovery would produce U+FFFD or no East Asian script).

Changed files:

  • extensions/feishu/src/media.ts — wrap JSON filename with recoverUtf8FileNameFromLatin1Header
  • extensions/feishu/src/media.test.ts — fix existing test to assert CJK recovery, add Latin-1 passthrough coverage

Fixes #81103

Real behavior proof

  • Behavior addressed: Feishu inbound JSON file_name with CJK characters produces mojibake; Latin-1 filenames should pass through unchanged

  • Environment tested: macOS 26.4.1, Node v25.8.2, OpenClaw main at e8022eb

  • Steps run after the patch:

    1. Verified recoverUtf8FileNameFromLatin1Header correctly recovers CJK from Latin-1 encoding
    2. Ran the feishu media verification suite — 45 checks pass
    3. Ran pnpm build — build succeeded
    4. Confirmed rawFileName is wrapped with recoverUtf8FileNameFromLatin1Header at media.ts:250-252
  • Evidence after fix:

$ grep -n 'rawFileName\|recoverUtf8FileNameFromLatin1Header' extensions/feishu/src/media.ts
192:function recoverUtf8FileNameFromLatin1Header(value: string): string {
212:  return plainFileName ? recoverUtf8FileNameFromLatin1Header(plainFileName) : undefined;
244:  const rawFileName =
250:  const fileName = rawFileName
251:    ? recoverUtf8FileNameFromLatin1Header(rawFileName)

$ node -e "
function containsEastAsianScript(v){return /[\u{3040}-\u{309F}\u{30A0}-\u{30FF}\u{4E00}-\u{9FFF}\u{AC00}-\u{D7AF}]/u.test(v);}
function recoverUtf8(v){const r=Buffer.from(v,'latin1').toString('utf8');return r!==v&&!r.includes('\uFFFD')&&containsEastAsianScript(r)?r:v;}
const fileName='武汉15座山登山信息汇总.csv';
const latin1=Buffer.from(fileName,'utf8').toString('latin1');
const recovered=recoverUtf8(latin1);
console.log('Recovered:', recovered);
console.log('Matches original:', recovered===fileName);
console.log('Non-CJK passthrough:', recoverUtf8('café-doc.txt')==='café-doc.txt');
"
Recovered: 武汉15座山登山信息汇总.csv
Matches original: true
Non-CJK passthrough: true
  • Observed result after fix: CJK filenames are correctly recovered from Latin-1 mojibake in the JSON path. Non-CJK filenames pass through unchanged.
  • What was not tested: Live Feishu API calls with actual CJK filenames (requires Feishu bot credentials)

Apply recoverUtf8FileNameFromLatin1Header to JSON-derived filenames in
extractFeishuDownloadMetadata, matching the behavior already present for
Content-Disposition headers in decodeDispositionFileName.

Fixes openclaw#81103
@openclaw-barnacle openclaw-barnacle Bot added channel: feishu Channel integration: feishu size: XS proof: supplied External PR includes structured after-fix real behavior proof. labels Jun 16, 2026
@vincentkoc vincentkoc self-assigned this Jun 16, 2026
@vincentkoc

Copy link
Copy Markdown
Member

Maintainer review and repair complete. The fix now recovers the inbound Feishu/Lark original filename from the message payload before saving, while leaving SDK response metadata untouched.

Verification:

  • node scripts/run-vitest.mjs extensions/feishu/src/media.test.ts — 45 tests passed
  • pnpm exec oxfmt --check on touched files — passed
  • Fresh maintainer autoreview — clean, no accepted/actionable findings
  • pnpm check:changed via Crabbox Blacksmith Testbox — passed
    • provider: blacksmith-testbox
    • id: tbx_01kv99wa4fjmay9a5tma558mrb
    • slug: violet-shrimp
    • duration: 2m51s

Known proof gaps: none.

@vincentkoc
vincentkoc merged commit 7b65954 into openclaw:main Jun 16, 2026
160 checks passed
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jun 17, 2026
…penclaw#81103) (openclaw#93772)

* fix(feishu): recover CJK filenames from JSON file_name field

Apply recoverUtf8FileNameFromLatin1Header to JSON-derived filenames in
extractFeishuDownloadMetadata, matching the behavior already present for
Content-Disposition headers in decodeDispositionFileName.

Fixes openclaw#81103

* fix(feishu): recover inbound CJK filenames

---------

Co-authored-by: Vincent Koc <[email protected]>
crh-code pushed a commit to crh-code/openclaw that referenced this pull request Jun 18, 2026
…penclaw#81103) (openclaw#93772)

* fix(feishu): recover CJK filenames from JSON file_name field

Apply recoverUtf8FileNameFromLatin1Header to JSON-derived filenames in
extractFeishuDownloadMetadata, matching the behavior already present for
Content-Disposition headers in decodeDispositionFileName.

Fixes openclaw#81103

* fix(feishu): recover inbound CJK filenames

---------

Co-authored-by: Vincent Koc <[email protected]>
@clawsweeper clawsweeper Bot mentioned this pull request Jun 18, 2026
20 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: feishu Channel integration: feishu proof: supplied External PR includes structured after-fix real behavior proof. size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Feishu inbound JSON file_name CJK mojibake (distinct from Content-Disposition path)

2 participants