Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix a bug in the recursive rmdir #39074

Closed
wants to merge 1 commit into from

Conversation

ajabep
Copy link

@ajabep ajabep commented Jun 29, 2023

Summary

The rmdirr tried to delete a non-empty directory, thus, it was failing.


A directory containing a directory containing files where never deleted.

Example:

Let's consider this configuration:

/tmp/root
└── intermediate
    ├── file1
    ├── file2
    └── file3

This configuration was able to occured during a plugin update.

If NC was running a rmdirr("/tmp/root"); (which seems to be done during a cron, but, that's not important), it would never deleted anything.

Indeed, the $files variable would contians only the intermediate directory.

Thus, during the loop to delete the content of the /tmp/root content, when $fileInfo will contains the descriptor of /tmp/root/intermediate, the rmdir PHP function would fails because this directory is not empty.... And maked the final rmdir (in the $deleteSelf condition).

Tested on PHP 8.1.20 (built: Jun 15 2023 01:23:25) (NTS), the PHP version of the docker container provided by NC-AIO.

Checklist

  • Code should be properly formatted (linted using php -l and tested in prod on my server)
  • Sign-off message is added to all commits
  • Tests (unit, integration, api and/or acceptance) are not included. I am currently testing it on my server, and it seems that does not break. I also have doubt about the presence of unit testing on this topic, else, the TypeError should never become in prod.
  • No screenshots before/after for front-end changes: not a UI change.
  • No Documentation (manuals or wiki) is required: not a new feature.
  • No Backports requested, but feel free to request it.

A directory containing a directory containing files where never deleted.

Example:

Let's consider this configuration:

```
/tmp/root
└── intermediate
	├── file1
	├── file2
    └── file3
```

This configuration was able to occured during a plugin update.

If NC was running a `rmdirr("/tmp/root");` (which seems to be done during a cron, but, that's not important), it would never deleted anything.

Indeed, the `$files` variable would contians only the `intermediate` directory.

Thus, during the loop to delete the content of the `/tmp/root` content, when `$fileInfo` will contains the descriptor of `/tmp/root/intermediate`, the `rmdir` PHP function would fails because this directory is not empty.... And maked the final `rmdir` (in the `$deleteSelf` condition).

Tested on `PHP 8.1.20 (built: Jun 15 2023 01:23:25) (NTS)`, the PHP version of the docker container provided by NC-AIO.

Signed-off-by: Ajabep <ajabep@tutanota.com>
@solracsf solracsf added this to the Nextcloud 28 milestone Jun 30, 2023
@solracsf solracsf added the 3. to review Waiting for reviews label Jun 30, 2023
@szaimen szaimen requested review from a team, ArtificialOwl, icewind1991, Fenn-CS and kesselb and removed request for a team July 27, 2023 22:31
@icewind1991
Copy link
Member

The RecursiveIteratorIterator::CHILD_FIRST should cause any items in the folder to be deleted before that rmdir is hit

@ajabep
Copy link
Author

ajabep commented Sep 21, 2023

The RecursiveIteratorIterator::CHILD_FIRST should cause any items in the folder to be deleted before that rmdir is hit

Actually, maybe it's a but in PHP (version used in your docker images), maybe it's a bad documentation, but, it was also what I thought initially ;-)

@skjnldsv skjnldsv mentioned this pull request Nov 1, 2023
@kesselb kesselb added 2. developing Work in progress and removed 3. to review Waiting for reviews labels Nov 1, 2023
@kesselb
Copy link
Contributor

kesselb commented Nov 1, 2023

We did a lot of debugging about iterators in nextcloud/updater#510 / php/doc-en#2903.

It appears that in some constellations, it's not safe to modify the file system while iterating.
I assume that is also the case here, and therefore should be fixed by iterating first and modifying afterward.

For example: https://github.com/nextcloud/updater/blob/55eca48fc6ed8b0f773dc3f14db84befa9ee1da9/lib/Updater.php#L776-L816 or by using iterator_to_array.

This was referenced Nov 6, 2023
This was referenced Nov 14, 2023
@blizzz blizzz modified the milestones: Nextcloud 28, Nextcloud 29 Nov 23, 2023
This was referenced Mar 12, 2024
This was referenced Mar 20, 2024
@skjnldsv skjnldsv mentioned this pull request Mar 28, 2024
81 tasks
@skjnldsv skjnldsv modified the milestones: Nextcloud 29, Nextcloud 30 Mar 28, 2024
@ajabep
Copy link
Author

ajabep commented Apr 10, 2024

I no longer use NextCloud, so, I can't test if the problem persists on stable versions. Feel free to reuse and adapt this MR if still needed.
I am closing it because I no longer have time to test it and adapt it.

@ajabep ajabep closed this Apr 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2. developing Work in progress
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants