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
if ( !is_array( $flags ) ) {
$flags = array( $flags );
}
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';
}
}
$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.
/**
* Force a class to be autoloaded from a specific path, regardless of where
* or if it was detected.
* @param string $inputPath Full path to the file containing the class
*/
public function forceClassPath( $fqcn, $inputPath ) {
* @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" );
}
if ( !$path ) {
throw new \Exception( "Invalid path: $inputPath" );
}
* @param string $inputPath Path to a php file to find classes within
*/
public function readFile( $inputPath ) {
* @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" );
$len = strlen( $this->basepath );
if ( substr( $inputPath, 0, $len ) !== $this->basepath ) {
throw new \Exception( "Path is not within basepath: $inputPath" );
*/
public function readDir( $dir ) {
$it = new RecursiveDirectoryIterator(
*/
public function readDir( $dir ) {
$it = new RecursiveDirectoryIterator(
- self::platformAgnosticRealpath( $dir ) );
+ self::normalizePathSeparator( realpath( $dir ) ) );
$it = new RecursiveIteratorIterator( $it );
foreach ( $it as $path => $file ) {
$it = new RecursiveIteratorIterator( $it );
foreach ( $it as $path => $file ) {
+
+ /**
+ * 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 );
+ }