[
https://issues.apache.org/jira/browse/GROOVY-12359?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Daniel Sun resolved GROOVY-12359.
---------------------------------
Fix Version/s: 6.0.0-RC-2
Resolution: Fixed
> deleteDir: treat Windows directory junctions as leaves, as symbolic links
> already are
> -------------------------------------------------------------------------------------
>
> Key: GROOVY-12359
> URL: https://issues.apache.org/jira/browse/GROOVY-12359
> Project: Groovy
> Issue Type: Improvement
> Reporter: Paul King
> Assignee: Paul King
> Priority: Major
> Fix For: 6.0.0-RC-2
>
>
> Since GROOVY-12125, {{File.deleteDir()}} and the {{groovy-nio}}
> {{Path.deleteDir()}} treat a symbolic link as a leaf: the link is removed,
> and the directory it points at is not entered. The guard is
> {{Files.isSymbolicLink}}, and its own comment records the gap this ticket
> closes:
> {code:java}
> // never follow a symbolic link into its target; remove the link itself.
> // Note: Files.isSymbolicLink does not detect Windows directory junctions
> // (reparse points), which are therefore still traversed.
> {code}
> A junction inside a tree being deleted is followed, and the *target's*
> contents are deleted. Two things make this the half of the link problem worth
> code rather than documentation:
> * creating a junction needs no privilege — {{mklink /J}} works for any user,
> where Windows symbolic links require a privilege most users do not hold, so
> the unprivileged local actor's tool is exactly the one the guard misses;
> * it needs no timing — a junction is planted in advance and waits, unlike the
> check-then-delete race, which requires writing into the tree concurrently
> during deletion and is out of scope here (the threat model's local adversary
> is not granted that; addressed separately).
> h3. Proposed change
> Replace the symlink-only test at both decision points (the root check and the
> per-child check) in both implementations with an attribute read that refuses
> to treat any reparse point as an ordinary directory:
> {code:java}
> BasicFileAttributes attrs = Files.readAttributes(path,
> BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);
> boolean leaf = attrs.isSymbolicLink() || attrs.isOther(); // symlink,
> junction, or other reparse point
> {code}
> On POSIX, {{isOther()}} is false for ordinary files and directories, so
> behaviour there does not change. A junction is then deleted as the link node
> it is, matching the existing symlink behaviour.
> h3. Verification
> Junctions do not exist on POSIX, so this cannot be exercised on the
> development machine; the expected {{isOther()}} attribute behaviour for a
> junction is confirmed by the test rather than assumed in advance. The
> regression test is Windows-gated: it creates a junction with {{cmd /c mklink
> /J}} — which succeeds unprivileged on the CI runners — points it at a
> directory holding a marker file, deletes the enclosing tree, and asserts the
> marker survives and the junction node is gone. On other platforms the test is
> skipped; the existing symlink tests from GROOVY-12125 continue to cover the
> POSIX side.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)