From 62f7ad97fe6f730f4181e223c6bba4f5a7cd2e19 Mon Sep 17 00:00:00 2001 From: Lily Dayton Date: Mon, 8 Jun 2026 15:43:44 +0300 Subject: [PATCH] Guard find -fprint/-fprintf/-fls (they write to a file) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These actions write find's output to a file, truncating it — the same destructive effect as a `> file` redirect, which Dippy already asks on. They were grouped with -print/-printf/-ls (stdout, safe) by name, but the `f` prefix means 'file'. Route them to ask alongside -delete. Fixes #150. --- src/dippy/cli/find.py | 9 +++++++++ tests/cli/test_find.py | 12 ++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/dippy/cli/find.py b/src/dippy/cli/find.py index 5f3f139..1493968 100644 --- a/src/dippy/cli/find.py +++ b/src/dippy/cli/find.py @@ -14,6 +14,11 @@ COMMANDS = ["find"] +# Actions that write find's output to a file (truncating it) — same effect as a +# `> file` redirect, which Dippy already guards. The `f` prefix means "file" +# (vs. -print/-printf/-ls which write to stdout and are safe). +FILE_WRITE_ACTIONS = frozenset({"-fprint", "-fprint0", "-fprintf", "-fls"}) + # Context for flags that aren't self-explanatory FLAG_CONTEXT = { "-ok": "execute with prompt", @@ -36,6 +41,10 @@ def classify(ctx: HandlerContext) -> Classification: if token == "-delete": return Classification("ask", description=f"{base} -delete") + # -fprint/-fprintf/-fls write output to a file (truncating it) + if token in FILE_WRITE_ACTIONS: + return Classification("ask", description=f"{base} {token}") + # -exec/-execdir - extract inner command and delegate if token in ("-exec", "-execdir"): inner_tokens = [] diff --git a/tests/cli/test_find.py b/tests/cli/test_find.py index a4dd874..edaad3f 100644 --- a/tests/cli/test_find.py +++ b/tests/cli/test_find.py @@ -138,10 +138,6 @@ ("find . -printf '%f\\n'", True), ("find . -printf '%p %s\\n'", True), ("find . -ls", True), - ("find . -fls /tmp/output.txt", True), - ("find . -fprint /tmp/output.txt", True), - ("find . -fprint0 /tmp/output.txt", True), - ("find . -fprintf /tmp/output.txt '%p\\n'", True), # # --- Boolean operators (safe) --- # @@ -251,6 +247,14 @@ ("find /tmp -name '*.cache' -delete", False), ("find . -mtime +30 -delete", False), # + # --- -fprint/-fprintf/-fls (write output to a file, truncating it) --- + # + ("find . -fprint /tmp/output.txt", False), + ("find . -fprint0 /tmp/output.txt", False), + ("find . -fprintf /tmp/output.txt '%p\\n'", False), + ("find . -fls /tmp/output.txt", False), + ("find . -name '*.py' -fprint /etc/hosts", False), + # # --- Combinations with safe exec --- # ("find . -name '*.py' -print -exec cat {} \\;", True),