fix(recency): find -printf uses \n record separator — breaks on filenames containing newlines #86

Open
opened 2026-04-18 20:24:38 -06:00 by claude-code · 0 comments
Collaborator

Problem

find_recent_files uses a newline-separated record format and splits on newline:

luminos_lib/recency.py:20:

cmd.extend(["-printf", "%T@\t%p\n"])

luminos_lib/recency.py:34:

for line in result.stdout.strip().split("\n"):

A filename containing a literal \n (valid on POSIX filesystems) produces a record that looks like two records when split. The second half then fails the parts = line.split("\t", 1) / float(parts[0]) checks and is silently dropped. The first half has the timestamp but a truncated path — so it's either silently dropped (if the truncated path fails float) or surfaces a wrong path in the "recent files" list.

Severity

Low: newline-in-filename is rare in practice. But the fix is small and the current silent-corruption mode is worse than no result.

Fix

Use NUL as the record separator:

cmd.extend(["-printf", "%T@\t%p\0"])

And split on "\x00":

for line in result.stdout.split("\x00"):
    if not line:
        continue
    parts = line.split("\t", 1)
    ...

Same pattern works in classify_files if this ever gets ported to use find, and in any future helper that shells out to find -print.

Acceptance

  • recency.py uses NUL separator
  • A file with a newline in its name shows up correctly in recent files (or is excluded cleanly, not corrupted)
  • tests/test_recency.py gets a case for newline-in-filename (mocked subprocess output)
## Problem `find_recent_files` uses a newline-separated record format and splits on newline: `luminos_lib/recency.py:20`: ```python cmd.extend(["-printf", "%T@\t%p\n"]) ``` `luminos_lib/recency.py:34`: ```python for line in result.stdout.strip().split("\n"): ``` A filename containing a literal `\n` (valid on POSIX filesystems) produces a record that looks like two records when split. The second half then fails the `parts = line.split("\t", 1)` / `float(parts[0])` checks and is silently dropped. The first half has the timestamp but a truncated path — so it's either silently dropped (if the truncated path fails `float`) or surfaces a wrong path in the "recent files" list. ## Severity Low: newline-in-filename is rare in practice. But the fix is small and the current silent-corruption mode is worse than no result. ## Fix Use NUL as the record separator: ```python cmd.extend(["-printf", "%T@\t%p\0"]) ``` And split on `"\x00"`: ```python for line in result.stdout.split("\x00"): if not line: continue parts = line.split("\t", 1) ... ``` Same pattern works in `classify_files` if this ever gets ported to use `find`, and in any future helper that shells out to `find -print`. ## Acceptance - [ ] `recency.py` uses NUL separator - [ ] A file with a newline in its name shows up correctly in recent files (or is excluded cleanly, not corrupted) - [ ] `tests/test_recency.py` gets a case for newline-in-filename (mocked subprocess output)
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: archeious/luminos#86
No description provided.