From 5e2c34fec35ac2863c4cba40ad49e47837ccd4e6 Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Sat, 20 Dec 2014 12:05:29 -0700 Subject: [PATCH] Fix AutoloadGenerator to work on MediaWiki-Vagrant (again) The patch set from I5d502b5 re-introduced the use of realpath() within AutoloadGenerator::readFile() as part of a set of changes to ensure that path separators are normalized across Unix and Windows systems. As noted previously in I4623b3d, the use of realpath() in this function will cause fatal exceptions to be thrown when a file such as LocalSettings.php is a symlink to a file outside to $IP. This patch separates the path normalization functionality from realpath() expansion and uses only the path normalization component within AutoloadGenerator::readFile(). It also introduces a cautionary comment in AutoloadGenerator::readFile() that will hopefully keep realpath() from being reintroduced there. Change-Id: I4923dfa8370a7bd6077f42ff4c437d7293fdad66 --- includes/utils/AutoloadGenerator.php | 32 +++++++++++++++------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/includes/utils/AutoloadGenerator.php b/includes/utils/AutoloadGenerator.php index 6149a23f33..0d0907b330 100644 --- a/includes/utils/AutoloadGenerator.php +++ b/includes/utils/AutoloadGenerator.php @@ -50,24 +50,13 @@ class AutoloadGenerator { if ( !is_array( $flags ) ) { $flags = array( $flags ); } - $this->basepath = self::platformAgnosticRealpath( $basepath ); + $this->basepath = self::normalizePathSeparator( realpath( $basepath ) ); $this->collector = new ClassCollector; if ( in_array( 'local', $flags ) ) { $this->variableName = 'wgAutoloadLocalClasses'; } } - /** - * Wrapper for realpath() that returns the same results (using forward - * slashes) on both Windows and *nix. - * - * @param string $path Parameter to realpath() - * @return string - */ - protected static function platformAgnosticRealpath( $path ) { - return str_replace( '\\', '/', realpath( $path ) ); - } - /** * Force a class to be autoloaded from a specific path, regardless of where * or if it was detected. @@ -76,7 +65,7 @@ class AutoloadGenerator { * @param string $inputPath Full path to the file containing the class */ public function forceClassPath( $fqcn, $inputPath ) { - $path = self::platformAgnosticRealpath( $inputPath ); + $path = self::normalizePathSeparator( realpath( $inputPath ) ); if ( !$path ) { throw new \Exception( "Invalid path: $inputPath" ); } @@ -92,7 +81,10 @@ class AutoloadGenerator { * @param string $inputPath Path to a php file to find classes within */ public function readFile( $inputPath ) { - $inputPath = self::platformAgnosticRealpath( $inputPath ); + // NOTE: do NOT expand $inputPath using realpath(). It is perfectly + // reasonable for LocalSettings.php and similiar files to be symlinks + // to files that are outside of $this->basepath. + $inputPath = self::normalizePathSeparator( $inputPath ); $len = strlen( $this->basepath ); if ( substr( $inputPath, 0, $len ) !== $this->basepath ) { throw new \Exception( "Path is not within basepath: $inputPath" ); @@ -112,7 +104,7 @@ class AutoloadGenerator { */ public function readDir( $dir ) { $it = new RecursiveDirectoryIterator( - self::platformAgnosticRealpath( $dir ) ); + self::normalizePathSeparator( realpath( $dir ) ) ); $it = new RecursiveIteratorIterator( $it ); foreach ( $it as $path => $file ) { @@ -183,6 +175,16 @@ global \${$this->variableName}; EOD ); } + + /** + * Ensure that Unix-style path separators ("/") are used in the path. + * + * @param string $path + * @return string + */ + protected static function normalizePathSeparator( $path ) { + return str_replace( '\\', '/', $path ); + } } /** -- 2.20.1