acpmux: refuse Windows device names (CON, NUL, COM1) for dropped files

Merged
TE
16d ago
+58-4

Summary

A file the person drops into a chat is saved by name under acpmux's uploads folder (_acpmux/file_put, #23324). On Windows, a name such as CON, nul.txt, COM1.log, CONIN$, or one ending in a dot or a space, does not name a file in that folder: it opens a device, or the name is silently changed. is_file_name now refuses these names on Windows, the same way it already refused \ and : there.

  • The stem is the part before the first dot, with trailing spaces trimmed and compared case-insensitively. A stem of CON, PRN, AUX, NUL, CONIN$ or CONOUT$ is refused.
  • COM or LPT followed by exactly one of 1-9, ¹, ² or ³ is refused.
  • A name ending in . or is refused.
  • Names that only look similar are kept: CONSOLE.txt, COM10, COM0, nullable.rs, aux_data.csv, LPT.

Other platforms are unchanged. The check sits behind is_file_name_for(name, windows), so the Windows rules can be tested on Linux.

Testing

Focused command: cmux-tui.yml dispatch, mode=focused. The new test is hub::file_uploads::tests::a_windows_device_name_is_no_file_name_on_windows.

  • Red at c13a48ca, the test commit (run 39633604233, filter windows_device_name): it fails to compile because is_file_name_for doesn't exist yet. The test calls the Windows rules directly, so before this change there was nothing to call.
  • Green at 59b868bd (run 39633616267, filter file): all four file_uploads tests pass, the new one included.
  • cargo check --target x86_64-pc-windows-gnu passes (run 39633630080).

Observed / Not run

  • Observed: the red and green runs above. In the green run, the only other reds are already red on base and unrelated to this change:
    • clippy redundant clone in cmux-tui-core;
    • MSRV could not fetch the cmux-codex-acp git dependency;
    • cli::tests::action_surface_parity::pane_open_files_and_find_as_run_their_actions_with_a_path, which the file filter picked up.
  • Not run: a real Windows file save. Only the name check is tested.

Changelog

Fixed: a file dropped into a chat on Windows can no longer be saved under a device name such as CON or NUL.

No capture: daemon-only change with no UI.

Agent session: cosmic-gray

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Fixes acpmux file saving on Windows so names like CON, NUL, COM1, or names ending in a dot or space are rejected, instead of opening a device or getting silently renamed.

  • Adds a Windows-only device-name check covering CON, PRN, AUX, NUL, COM1-9, LPT1-9, CONIN$, and CONOUT$ with any extension, plus trailing-dot and trailing-space names.
  • Refactors the name check into is_file_name_for(name, windows) so the Windows rules can be tested on any platform. Other platforms are unchanged.