Skip to content

Commit a75d052

Browse files
authored
Merge pull request #196 from pbiron/case-insensitive-filename-compare
2 parents 5bcfd6a + 80b8c1c commit a75d052

File tree

2 files changed

+140
-2
lines changed

2 files changed

+140
-2
lines changed

features/core-update.feature

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ Feature: Update WordPress core
202202
Success: WordPress updated successfully.
203203
"""
204204

205-
When I run `wp core verify-checksums`
205+
# Allow for warnings to be produced.
206+
When I try `wp core verify-checksums`
206207
Then STDOUT should be:
207208
"""
208209
Success: WordPress installation verifies against checksums.
@@ -250,6 +251,81 @@ Feature: Update WordPress core
250251
When I run `wp post create --post_title='Test post' --porcelain`
251252
Then STDOUT should be a number
252253

254+
Scenario: Make sure files are cleaned up with mixed case
255+
Given a WP install
256+
And I try `wp theme install twentytwenty --activate`
257+
258+
When I run `wp core update --version=5.8 --force`
259+
Then the wp-includes/Requests/Transport/cURL.php file should exist
260+
Then the wp-includes/Requests/Exception/Transport/cURL.php file should exist
261+
Then the wp-includes/Requests/Exception/HTTP/502.php file should exist
262+
Then the wp-includes/Requests/IRI.php file should exist
263+
Then the wp-includes/Requests/Transport/Curl.php file should not exist
264+
Then the wp-includes/Requests/Exception/Transport/Curl.php file should not exist
265+
Then the wp-includes/Requests/Exception/Http/Status502.php file should not exist
266+
Then the wp-includes/Requests/Iri.php file should not exist
267+
268+
When I run `wp core update --version=5.9-beta1 --force`
269+
Then the wp-includes/Requests/Transport/cURL.php file should not exist
270+
Then the wp-includes/Requests/Exception/Transport/cURL.php file should not exist
271+
Then the wp-includes/Requests/Exception/HTTP/502.php file should not exist
272+
Then the wp-includes/Requests/IRI.php file should not exist
273+
Then the wp-includes/Requests/Transport/Curl.php file should exist
274+
Then the wp-includes/Requests/Exception/Transport/Curl.php file should exist
275+
Then the wp-includes/Requests/Exception/Http/Status502.php file should exist
276+
Then the wp-includes/Requests/Iri.php file should exist
277+
Then STDOUT should contain:
278+
"""
279+
File removed: wp-includes/Requests/Transport/fsockopen.php
280+
File removed: wp-includes/Requests/Transport/cURL.php
281+
File removed: wp-includes/Requests/Hooker.php
282+
File removed: wp-includes/Requests/IPv6.php
283+
File removed: wp-includes/Requests/Exception/Transport/cURL.php
284+
File removed: wp-includes/Requests/Exception/HTTP.php
285+
File removed: wp-includes/Requests/Exception/HTTP/502.php
286+
File removed: wp-includes/Requests/Exception/HTTP/Unknown.php
287+
File removed: wp-includes/Requests/Exception/HTTP/412.php
288+
File removed: wp-includes/Requests/Exception/HTTP/408.php
289+
File removed: wp-includes/Requests/Exception/HTTP/431.php
290+
File removed: wp-includes/Requests/Exception/HTTP/501.php
291+
File removed: wp-includes/Requests/Exception/HTTP/500.php
292+
File removed: wp-includes/Requests/Exception/HTTP/407.php
293+
File removed: wp-includes/Requests/Exception/HTTP/416.php
294+
File removed: wp-includes/Requests/Exception/HTTP/428.php
295+
File removed: wp-includes/Requests/Exception/HTTP/406.php
296+
File removed: wp-includes/Requests/Exception/HTTP/504.php
297+
File removed: wp-includes/Requests/Exception/HTTP/411.php
298+
File removed: wp-includes/Requests/Exception/HTTP/414.php
299+
File removed: wp-includes/Requests/Exception/HTTP/511.php
300+
File removed: wp-includes/Requests/Exception/HTTP/410.php
301+
File removed: wp-includes/Requests/Exception/HTTP/403.php
302+
File removed: wp-includes/Requests/Exception/HTTP/400.php
303+
File removed: wp-includes/Requests/Exception/HTTP/505.php
304+
File removed: wp-includes/Requests/Exception/HTTP/413.php
305+
File removed: wp-includes/Requests/Exception/HTTP/404.php
306+
File removed: wp-includes/Requests/Exception/HTTP/306.php
307+
File removed: wp-includes/Requests/Exception/HTTP/304.php
308+
File removed: wp-includes/Requests/Exception/HTTP/405.php
309+
File removed: wp-includes/Requests/Exception/HTTP/429.php
310+
File removed: wp-includes/Requests/Exception/HTTP/417.php
311+
File removed: wp-includes/Requests/Exception/HTTP/409.php
312+
File removed: wp-includes/Requests/Exception/HTTP/402.php
313+
File removed: wp-includes/Requests/Exception/HTTP/418.php
314+
File removed: wp-includes/Requests/Exception/HTTP/305.php
315+
File removed: wp-includes/Requests/Exception/HTTP/415.php
316+
File removed: wp-includes/Requests/Exception/HTTP/401.php
317+
File removed: wp-includes/Requests/Exception/HTTP/503.php
318+
File removed: wp-includes/Requests/IRI.php
319+
File removed: wp-includes/Requests/IDNAEncoder.php
320+
File removed: wp-includes/Requests/SSL.php
321+
File removed: wp-includes/Requests/Proxy/HTTP.php
322+
"""
323+
324+
When I run `wp option add str_opt 'bar'`
325+
Then STDOUT should not be empty
326+
When I run `wp post create --post_title='Test post' --porcelain`
327+
Then STDOUT should be a number
328+
253329
@less-than-php-7.3
254330
Scenario: Minor update on an unlocalized WordPress release
255331
Given a WP install

src/Core_Command.php

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1372,7 +1372,69 @@ private function cleanup_extra_files( $version_from, $version_to, $locale, $inse
13721372
return;
13731373
}
13741374

1375-
$files_to_remove = array_diff( array_keys( $old_checksums ), array_keys( $new_checksums ) );
1375+
// Compare the files from the old version and the new version in a case-insensitive manner,
1376+
// to prevent files being incorrectly deleted on systems with case-insensitive filesystems
1377+
// when core changes the case of filenames.
1378+
// The main logic for this was taken from the Joomla project and adapted for WP.
1379+
// See: https://github.com/joomla/joomla-cms/blob/bb5368c7ef9c20270e6e9fcc4b364cd0849082a5/administrator/components/com_admin/script.php#L8158
1380+
1381+
$old_filepaths = array_keys( $old_checksums );
1382+
$new_filepaths = array_keys( $new_checksums );
1383+
1384+
$new_filepaths = array_combine( array_map( 'strtolower', $new_filepaths ), $new_filepaths );
1385+
1386+
$old_filepaths_to_check = array_diff( $old_filepaths, $new_filepaths );
1387+
1388+
foreach ( $old_filepaths_to_check as $old_filepath_to_check ) {
1389+
$old_realpath = realpath( ABSPATH . $old_filepath_to_check );
1390+
1391+
// On Unix without incorrectly cased file.
1392+
if ( false === $old_realpath ) {
1393+
continue;
1394+
}
1395+
1396+
$lowercase_old_filepath_to_check = strtolower( $old_filepath_to_check );
1397+
1398+
if ( ! array_key_exists( $lowercase_old_filepath_to_check, $new_filepaths ) ) {
1399+
$files_to_remove[] = $old_filepath_to_check;
1400+
continue;
1401+
}
1402+
1403+
// We are now left with only the files that are similar from old to new except for their case.
1404+
1405+
$old_basename = basename( $old_realpath );
1406+
$new_filepath = $new_filepaths[ $lowercase_old_filepath_to_check ];
1407+
$expected_basename = basename( $new_filepath );
1408+
$new_realpath = realpath( ABSPATH . $new_filepath );
1409+
$new_basename = basename( $new_realpath );
1410+
1411+
// On Windows or Unix with only the incorrectly cased file.
1412+
if ( $new_basename !== $expected_basename ) {
1413+
WP_CLI::debug( "Renaming file '{$old_filepath_to_check}' => '{$new_filepath}'", 'core' );
1414+
1415+
rename( ABSPATH . $old_filepath_to_check, ABSPATH . $old_filepath_to_check . '.tmp' );
1416+
rename( ABSPATH . $old_filepath_to_check . '.tmp', ABSPATH . $new_filepath );
1417+
1418+
continue;
1419+
}
1420+
1421+
// There might still be an incorrectly cased file on other OS than Windows.
1422+
if ( basename( $old_filepath_to_check ) === $old_basename ) {
1423+
// Check if case-insensitive file system, eg on OSX.
1424+
if ( fileinode( $old_realpath ) === fileinode( $new_realpath ) ) {
1425+
// Check deeper because even realpath or glob might not return the actual case.
1426+
if ( ! in_array( $expected_basename, scandir( dirname( $new_realpath ) ), true ) ) {
1427+
WP_CLI::debug( "Renaming file '{$old_filepath_to_check}' => '{$new_filepath}'", 'core' );
1428+
1429+
rename( ABSPATH . $old_filepath_to_check, ABSPATH . $old_filepath_to_check . '.tmp' );
1430+
rename( ABSPATH . $old_filepath_to_check . '.tmp', ABSPATH . $new_filepath );
1431+
}
1432+
} else {
1433+
// On Unix with both files: Delete the incorrectly cased file.
1434+
$files_to_remove[] = $old_filepath_to_check;
1435+
}
1436+
}
1437+
}
13761438

13771439
if ( ! empty( $files_to_remove ) ) {
13781440
WP_CLI::log( 'Cleaning up files...' );

0 commit comments

Comments
 (0)