[ 
https://issues.apache.org/jira/browse/IO-751?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17422068#comment-17422068
 ] 

Richard Cyganiak commented on IO-751:
-------------------------------------

So you say the semantics of {{PathUtils.setReadOnly}} are:

bq. Read-only false: Allow reading, allow writing

Ok. This seems to fix half of the problem. On to the other half.

I believe that {{StandardDeleteOptions.OVERRIDE_READ_ONLY}} does not work at 
all on POSIX file systems.

The implementation (in {{DeletingPathVisitor}}, {{CleaningPathVisitor}}, 
{{PathUtils.deleteFile}}, and possibly elsewhere) assumes that to delete a 
file, it is necessary to be allowed to write to the file (achieved by calling 
{{PathUtils.setReadOnly(p, false, ...)}}).

This assumption is not true on POSIX file systems. There, to delete a file you 
need write and execute permission _on the directory_ that contains the file. I 
don't think you need write permission on the file at all, nor be the owner of 
the file.

The same applies when deleting directories and symlinks.

In other words, the call to {{PathUtils.setReadOnly(p, false, ...)}} before 
deleting a resource does not achieve the intended purpose, because it's the 
_parent's_ permissions that matter. It also has an unintended side effect in 
case the resource is a symlink, because the call changes the permissions of the 
symlink's _target_ before deleting the symlink itself, and this leaves an 
unrelated resource that we were not trying to delete in an altered state.

> When deleting symlinks, File/PathUtils.deleteDirectory() changes file 
> permissions of the target
> -----------------------------------------------------------------------------------------------
>
>                 Key: IO-751
>                 URL: https://issues.apache.org/jira/browse/IO-751
>             Project: Commons IO
>          Issue Type: Bug
>          Components: Utilities
>    Affects Versions: 2.11.0
>         Environment: macOS 11.5.2
> OpenJDK 11
>            Reporter: Richard Cyganiak
>            Priority: Major
>         Attachments: DeleteDirectoryTest.java, commons-io.patch
>
>
> 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?



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to