When FileUtils.deleteDirectory(...) and PathUtils.deleteDirectory(...) encounter a symlink while recursively deleting, the default behaviour is to delete the symlink, but leave the target of the symlink alone. This works for the most part: the symlink is correctly deleted, and the target is not deleted or recursed into.
However, the methods alter the file permissions of the target:
- FileUtils.deleteDirectory(file) removes all write permissions from the target
- PathUtils.deleteDirectory(path, StandardDeleteOption.OVERRIDE_READ_ONLY) removes all write permissions, and adds all execute permissions (even if the target is a file, not a directory)
- PathUtils.deleteDirectory(path) works correctly and does not change the target's permissions
A JUnit 4 test case that demonstrates the behaviour of all three methods is attached.
The behaviour is unexpected (the Javadocs give no hint), inconvenient (it leaves the owner of the target without write permission) and potentially dangerous (it adds execute permissions for anyone).
It appears the implementation assumes it can freely modify permissions because it is going to delete the file/directory anyway, and the case of symlinks was simply not considered. The handling of write permissions is particularly puzzling. I could understand why an implementation would add write permission, but why remove it?