@@ -2033,7 +2033,6 @@ private function remove_directory( $dir, $abspath_realpath_trailing ) {
20332033 WP_CLI ::debug ( "Failed to resolve realpath for directory: {$ dir }" , 'core ' );
20342034 return false ;
20352035 }
2036- // Normalize paths with trailing slashes for accurate comparison
20372036 if ( 0 !== strpos ( $ dir_realpath , $ abspath_realpath_trailing ) ) {
20382037 WP_CLI ::debug ( "Attempted to remove directory outside of ABSPATH: {$ dir_realpath }" , 'core ' );
20392038 return false ;
@@ -2042,35 +2041,36 @@ private function remove_directory( $dir, $abspath_realpath_trailing ) {
20422041 return false ;
20432042 }
20442043
2045- $ items = scandir ( $ dir );
2046- if ( false === $ items ) {
2047- WP_CLI ::debug ( "Failed to scan directory: {$ dir }" , 'core ' );
2048- return false ;
2049- }
2050-
2051- foreach ( $ items as $ item ) {
2052- if ( '. ' === $ item || '.. ' === $ item ) {
2053- continue ;
2054- }
2055-
2056- $ path = $ dir . DIRECTORY_SEPARATOR . $ item ;
2044+ $ files = new RecursiveIteratorIterator (
2045+ new RecursiveDirectoryIterator ( $ dir , RecursiveDirectoryIterator::SKIP_DOTS ),
2046+ RecursiveIteratorIterator::CHILD_FIRST
2047+ );
20572048
2058- // Handle symbolic links before checking if it's a directory
2059- if ( is_link ( $ path ) ) {
2049+ /** @var \SplFileInfo $fileinfo */
2050+ foreach ( $ files as $ fileinfo ) {
2051+ // Use the symlink's own path (not realpath) to avoid following it outside ABSPATH.
2052+ if ( $ fileinfo ->isLink () ) {
2053+ $ path = $ fileinfo ->getPathname ();
20602054 if ( ! unlink ( $ path ) ) {
20612055 WP_CLI ::debug ( "Failed to remove symbolic link: {$ path }" , 'core ' );
20622056 return false ;
20632057 }
20642058 continue ;
20652059 }
20662060
2067- if ( is_dir ( $ path ) ) {
2068- if ( ! $ this ->remove_directory ( $ path , $ abspath_realpath_trailing ) ) {
2069- WP_CLI ::debug ( "Failed to remove subdirectory: {$ path }" , 'core ' );
2061+ $ path = $ fileinfo ->getRealPath ();
2062+ if ( false === $ path || 0 !== strpos ( $ path , $ abspath_realpath_trailing ) ) {
2063+ WP_CLI ::debug ( "Attempted to remove path outside of ABSPATH: {$ path }" , 'core ' );
2064+ return false ;
2065+ }
2066+
2067+ if ( $ fileinfo ->isDir () ) {
2068+ if ( ! rmdir ( $ path ) ) {
2069+ WP_CLI ::debug ( "Failed to remove directory: {$ path }" , 'core ' );
20702070 return false ;
20712071 }
20722072 } elseif ( ! unlink ( $ path ) ) {
2073- WP_CLI ::debug ( "Failed to remove file in directory : {$ path }" , 'core ' );
2073+ WP_CLI ::debug ( "Failed to remove file: {$ path }" , 'core ' );
20742074 return false ;
20752075 }
20762076 }
0 commit comments