Anchored rules only fire when the scan root is absolute. Give the same
directory a relative path and every rule that starts with / stops
matching, so the files come back unknown and report::build drops
them.
The same file, twice:
$ diskern scan /var/tmp --top 2
Scanned 1 files.
Reclaimable: 3.0 MB across 1 findings and 0 duplicate sets.
Review first — 1 finding · 3.0 MB
Temporary files · 1 · 3.0 MB
3.0 MB /var/tmp/build-9a2f/out.o
matched rule temp-dirs: Temporary files. Usually safe once no program is using them.
$ cd /var && diskern scan tmp --top 2
Scanned 1 files.
Reclaimable: 0 B across 0 findings and 0 duplicate sets.
$ cd /var/tmp && diskern scan . --top 2
Scanned 1 files.
Reclaimable: 0 B across 0 findings and 0 duplicate sets.
jwalk yields paths built from the root as it was given, so the entries
are tmp/build-9a2f/out.o and ./build-9a2f/out.o. normalize only
lowercases and swaps separators, so /tmp/**, /var/tmp/**,
/private/var/tmp/** and /var/log/** — every pattern anchored at the
filesystem root — cannot match them.
Scanned 1 files is the tell: the walk found the file, the rules just
couldn't see where it was. It is the #82 failure in a different shape —
a plausible-looking empty result rather than an error — and it is worse
for --json, where nothing in the report says the paths were relative.
This is not new. Anchoring arrived in #41 and /tmp/** has behaved this
way since; #93 extends the same shape to var/tmp, which is what made it
worth writing down.
The fix is to make roots absolute before the walk, so patterns see the
path the rules were written against. std::path::absolute is the
conservative choice — it resolves . and relative prefixes without
touching the filesystem or following symlinks, which matters because
fs::canonicalize would rewrite /var/tmp to /private/var/tmp on
macOS and quietly change what the user asked to scan.
Two things worth deciding before implementing:
- Where. Doing it in
scanner::scan covers the app as well as the
CLI; doing it in the CLI leaves the engine taking roots exactly as
given. The engine is the one that owns what a path means, so it is
probably the right home.
- What it changes downstream.
FileEntry.path would become
absolute, and that path is what actions::quarantine records in the
manifest. Absolute is the safer thing to store there — a relative
original cannot be restored from a different working directory — so
this likely fixes a second problem, but it deserves a test rather than
an assumption.
A case in scanner.rs covering a relative root, and one in rules.rs
alongside rules_still_reach_the_paths_they_do_name, would pin it.
Anchored rules only fire when the scan root is absolute. Give the same
directory a relative path and every rule that starts with
/stopsmatching, so the files come back
unknownandreport::builddropsthem.
The same file, twice:
jwalkyields paths built from the root as it was given, so the entriesare
tmp/build-9a2f/out.oand./build-9a2f/out.o.normalizeonlylowercases and swaps separators, so
/tmp/**,/var/tmp/**,/private/var/tmp/**and/var/log/**— every pattern anchored at thefilesystem root — cannot match them.
Scanned 1 filesis the tell: the walk found the file, the rules justcouldn't see where it was. It is the #82 failure in a different shape —
a plausible-looking empty result rather than an error — and it is worse
for
--json, where nothing in the report says the paths were relative.This is not new. Anchoring arrived in #41 and
/tmp/**has behaved thisway since; #93 extends the same shape to
var/tmp, which is what made itworth writing down.
The fix is to make roots absolute before the walk, so patterns see the
path the rules were written against.
std::path::absoluteis theconservative choice — it resolves
.and relative prefixes withouttouching the filesystem or following symlinks, which matters because
fs::canonicalizewould rewrite/var/tmpto/private/var/tmponmacOS and quietly change what the user asked to scan.
Two things worth deciding before implementing:
scanner::scancovers the app as well as theCLI; doing it in the CLI leaves the engine taking roots exactly as
given. The engine is the one that owns what a path means, so it is
probably the right home.
FileEntry.pathwould becomeabsolute, and that path is what
actions::quarantinerecords in themanifest. Absolute is the safer thing to store there — a relative
original cannot be restored from a different working directory — so
this likely fixes a second problem, but it deserves a test rather than
an assumption.
A case in
scanner.rscovering a relative root, and one inrules.rsalongside
rules_still_reach_the_paths_they_do_name, would pin it.