[ 
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)

Reply via email to