diff --git a/cms/lib/handlers/handler_ws.php b/cms/lib/handlers/handler_ws.php index 458c55d..faaa35f 100755 --- a/cms/lib/handlers/handler_ws.php +++ b/cms/lib/handlers/handler_ws.php @@ -324,17 +324,24 @@ function _removeFile() { } function _deleteAll($str) { - if (!file_exists($str)) return false; - if (is_file($str)) { + if (!file_exists($str) && !is_link($str)) return false; + // Un symlink se quita, NUNCA se sigue: borrar su contenido seria borrar algo + // que vive fuera de la carpeta que se pidio borrar. + if (is_link($str) || is_file($str)) { return unlink($str); } elseif (is_dir($str)) { - //Get a list of the files in this directory. - $scan = glob(rtrim($str,'/').'/*'); - //Loop through the list of files. - foreach($scan as $index=>$path) { - //Call our recursive function. - _deleteAll($path); + // `scandir` y no `glob`: glob NO devuelve los ficheros ocultos, asi que + // un `.htaccess` sobrevivia al borrado, la carpeta no quedaba vacia y el + // rmdir de abajo fallaba en silencio. Con eso, desinstalar en produccion + // un plugin con .htaccess —5 de 14 en una web real— borraba su codigo, + // devolvia "no se ha podido desinstalar" y dejaba la operacion a medias: + // sin ficheros, pero con la carpeta y con el alta en el central. + $entradas = @scandir($str); + if ($entradas === false) return false; + foreach ($entradas as $nombre) { + if ($nombre === '.' || $nombre === '..') continue; + _deleteAll(rtrim($str, '/') . '/' . $nombre); } //Remove the directory itself. return @rmdir($str);