From f0ea8fdfb9a2976cd9148c7403ee9639cf9b6358 Mon Sep 17 00:00:00 2001 From: Elliott Eggleston Date: Thu, 12 Sep 2013 18:55:45 -0400 Subject: [PATCH] wfMkdirParents: recover from mkdir race condition If mkdir fails, check again to see if dir has been created since our initial check, and return true if so. Also, in initial check, only return true if $dir is really a directory, not a file. Bug: 49391 Change-Id: I2b331669fae70948ce79ba1477c05968a3095c3d --- includes/GlobalFunctions.php | 7 ++++++- tests/phpunit/includes/GlobalFunctions/GlobalTest.php | 9 +++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index bed2c44b03..f43393a880 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -2521,7 +2521,7 @@ function wfMkdirParents( $dir, $mode = null, $caller = null ) { wfDebug( "$caller: called wfMkdirParents($dir)\n" ); } - if ( strval( $dir ) === '' || file_exists( $dir ) ) { + if ( strval( $dir ) === '' || ( file_exists( $dir ) && is_dir( $dir ) ) ) { return true; } @@ -2537,6 +2537,11 @@ function wfMkdirParents( $dir, $mode = null, $caller = null ) { wfRestoreWarnings(); if ( !$ok ) { + //directory may have been created on another request since we last checked + if ( is_dir( $dir ) ) { + return true; + } + // PHP doesn't report the path in its warning message, so add our own to aid in diagnosis. wfLogWarning( sprintf( "failed to mkdir \"%s\" mode 0%o", $dir, $mode ) ); } diff --git a/tests/phpunit/includes/GlobalFunctions/GlobalTest.php b/tests/phpunit/includes/GlobalFunctions/GlobalTest.php index 6a2a0df783..244b100ec1 100644 --- a/tests/phpunit/includes/GlobalFunctions/GlobalTest.php +++ b/tests/phpunit/includes/GlobalFunctions/GlobalTest.php @@ -630,6 +630,15 @@ class GlobalTest extends MediaWikiTestCase { return $a; } + function testWfMkdirParents() { + // Should not return true if file exists instead of directory + $fname = $this->getNewTempFile(); + wfSuppressWarnings(); + $ok = wfMkdirParents( $fname ); + wfRestoreWarnings(); + $this->assertFalse( $ok ); + } + /** * @dataProvider provideWfShellMaintenanceCmdList */ -- 2.20.1