OpenClaw / OpenClaw Core
Merged upstreamCorrectnessMerged Sep 19, 2026

Preserve portable terminal upload names after truncation

Reapplied the existing trailing-dot/space and reserved-name checks after the 180-byte staging limit transforms a filename.

openclaw/openclaw · #153023

Filesystem portability fix

Long terminal-upload filenames retain trailing-character and Windows reserved-name protections after UTF-8 byte truncation.

Problem

The sanitizer normalized a name before truncation, but the final UTF-8 prefix could end in a dot or space. Trimming that suffix could then expose a reserved basename such as `CON`, producing a staged name that violated the sanitizer's own portability rules.

Approach

Keeps the existing shared Gateway/node staging implementation and normalization rules, then re-establishes portability invariants after truncation while preserving complete UTF-8 code points.

Impact and scope

  • Prevents deterministic non-portable staged basenames for long uploads whose byte boundary lands on a dot or space.
  • Retains reserved-name protection even when post-truncation cleanup reveals a Windows-reserved basename.
  • Leaves file contents, upload limits, private staging permissions, terminal ownership, and existing staged files unchanged.

Validation

  • A running Gateway, authenticated operator connection, and real local PTY reproduced five invalid long-name cases on the baseline and the expected portable names after the fix.
  • Twelve real terminal.upload calls per revision covered ordinary, Unicode, reserved/default, hostile, repeated, and whole-code-point-boundary names while verifying exact contents, sizes, distinct files, and 0700/0600 modes.
  • All 21 focused staging tests, targeted formatting/lint, the OpenClaw CI gate, dependency review, and security-sensitive review passed. The verified merge commit credits Goutam Adwant.
  • Runtime proof used secretless Linux/arm64 and the exact changed files on a pinned current-main runtime. It does not establish native Windows filesystem/ACL behavior, browser drag-and-drop, path insertion, paired-node routing, or a full execution of the older contributor tree.