mirror of
https://github.com/Terranom674/Piwigo_Bratonien_Tools.git
synced 2026-09-19 11:44:31 +00:00
Handle symlinks safely while removing detached cache trees
This commit is contained in:
@@ -8,24 +8,53 @@ function bratonien_tools_atomic_cache_remove_tree($root, array &$failed)
|
|||||||
{
|
{
|
||||||
if (!file_exists($root) && !is_link($root)) return;
|
if (!file_exists($root) && !is_link($root)) return;
|
||||||
|
|
||||||
$iterator = new RecursiveIteratorIterator(
|
// Niemals einem Symlink folgen. Auch ein Link auf ein Verzeichnis ist nur
|
||||||
new RecursiveDirectoryIterator($root, FilesystemIterator::SKIP_DOTS),
|
// ein einzelner Eintrag des ausgelagerten Cachebaums und wird per unlink()
|
||||||
RecursiveIteratorIterator::CHILD_FIRST
|
// entfernt. So kann das Cleanup kein Ziel ausserhalb des Cachebaums beruehren.
|
||||||
);
|
if (is_link($root))
|
||||||
|
|
||||||
foreach ($iterator as $item)
|
|
||||||
{
|
{
|
||||||
$path = $item->getPathname();
|
if (!@unlink($root)) $failed[] = $root;
|
||||||
if ($item->isLink() || $item->isFile())
|
return;
|
||||||
|
}
|
||||||
|
if (is_file($root))
|
||||||
|
{
|
||||||
|
if (!@unlink($root)) $failed[] = $root;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!is_dir($root))
|
||||||
|
{
|
||||||
|
$failed[] = $root;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$entries = @scandir($root);
|
||||||
|
if ($entries === false)
|
||||||
|
{
|
||||||
|
$failed[] = $root;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($entries as $entry)
|
||||||
|
{
|
||||||
|
if ($entry === '.' || $entry === '..') continue;
|
||||||
|
$path = $root.DIRECTORY_SEPARATOR.$entry;
|
||||||
|
|
||||||
|
if (is_link($path) || is_file($path))
|
||||||
{
|
{
|
||||||
if (!@unlink($path)) $failed[] = $path;
|
if (!@unlink($path)) $failed[] = $path;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($item->isDir() && !@rmdir($path))
|
if (is_dir($path))
|
||||||
{
|
{
|
||||||
$failed[] = $path;
|
bratonien_tools_atomic_cache_remove_tree($path, $failed);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sonderdateien werden wie einzelne Cacheeintraege behandelt. unlink()
|
||||||
|
// ist hier sicherer als ein rekursiver Iterator, der Verweise interpretieren
|
||||||
|
// koennte.
|
||||||
|
if (!@unlink($path)) $failed[] = $path;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!@rmdir($root) && is_dir($root)) $failed[] = $root;
|
if (!@rmdir($root) && is_dir($root)) $failed[] = $root;
|
||||||
@@ -86,10 +115,6 @@ function bratonien_tools_clear_image_cache_atomic()
|
|||||||
throw new RuntimeException('Temporäres Cache-Auslagerungsverzeichnis existiert bereits. Abbruch.');
|
throw new RuntimeException('Temporäres Cache-Auslagerungsverzeichnis existiert bereits. Abbruch.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Der gesamte bisherige Cache wird in einem einzigen Rename aus dem aktiven
|
|
||||||
// Piwigo-Pfad entfernt. Neue Requests schreiben danach nur noch in den neu
|
|
||||||
// angelegten Cachebaum und können nicht mit dem Löschen des Altbestands
|
|
||||||
// konkurrieren.
|
|
||||||
if (!@rename($real_cache_root, $detached))
|
if (!@rename($real_cache_root, $detached))
|
||||||
{
|
{
|
||||||
throw new RuntimeException('Bildcache konnte nicht atomar aus dem aktiven Pfad ausgelagert werden.');
|
throw new RuntimeException('Bildcache konnte nicht atomar aus dem aktiven Pfad ausgelagert werden.');
|
||||||
@@ -101,7 +126,6 @@ function bratonien_tools_clear_image_cache_atomic()
|
|||||||
umask($umask);
|
umask($umask);
|
||||||
if (!$created && !is_dir($real_cache_root))
|
if (!$created && !is_dir($real_cache_root))
|
||||||
{
|
{
|
||||||
// Der aktive Pfad muss in diesem Fehlerfall wiederhergestellt werden.
|
|
||||||
if (!file_exists($real_cache_root) && @rename($detached, $real_cache_root))
|
if (!file_exists($real_cache_root) && @rename($detached, $real_cache_root))
|
||||||
{
|
{
|
||||||
throw new RuntimeException('Neuer Bildcache konnte nicht angelegt werden; der bisherige Cache wurde vollständig wiederhergestellt.');
|
throw new RuntimeException('Neuer Bildcache konnte nicht angelegt werden; der bisherige Cache wurde vollständig wiederhergestellt.');
|
||||||
|
|||||||
Reference in New Issue
Block a user