Commit 63e434b4 by Klimov Paul

Safe real path resolving added to `yii\console\controllers\AssetController::combineCssFiles()`

parent 112ad80d
...@@ -512,9 +512,10 @@ EOD; ...@@ -512,9 +512,10 @@ EOD;
public function combineCssFiles($inputFiles, $outputFile) public function combineCssFiles($inputFiles, $outputFile)
{ {
$content = ''; $content = '';
$outputFilePath = dirname($this->findRealPath($outputFile));
foreach ($inputFiles as $file) { foreach ($inputFiles as $file) {
$content .= "/*** BEGIN FILE: $file ***/\n" $content .= "/*** BEGIN FILE: $file ***/\n"
. $this->adjustCssUrl(file_get_contents($file), dirname($file), dirname($outputFile)) . $this->adjustCssUrl(file_get_contents($file), dirname($this->findRealPath($file)), $outputFilePath)
. "/*** END FILE: $file ***/\n"; . "/*** END FILE: $file ***/\n";
} }
if (!file_put_contents($outputFile, $content)) { if (!file_put_contents($outputFile, $content)) {
...@@ -658,4 +659,26 @@ EOD; ...@@ -658,4 +659,26 @@ EOD;
echo "Configuration file template created at '{$configFile}'.\n\n"; echo "Configuration file template created at '{$configFile}'.\n\n";
} }
} }
/**
* Returns canonicalized absolute pathname.
* Unlike regular `realpath()` this method does not expand symlinks and does not check path existence.
* @param string $path raw path
* @return string canonicalized absolute pathname
*/
private function findRealPath($path)
{
$path = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $path);
$pathParts = explode(DIRECTORY_SEPARATOR, $path);
$realPathParts = [];
foreach ($pathParts as $pathPart) {
if ($pathPart === '..') {
array_pop($realPathParts);
} else {
array_push($realPathParts, $pathPart);
}
}
return implode(DIRECTORY_SEPARATOR, $realPathParts);
}
} }
...@@ -409,4 +409,51 @@ EOL; ...@@ -409,4 +409,51 @@ EOL;
$this->assertEquals($expectedCssContent, $adjustedCssContent, 'Unable to adjust CSS correctly!'); $this->assertEquals($expectedCssContent, $adjustedCssContent, 'Unable to adjust CSS correctly!');
} }
/**
* Data provider for [[testFindRealPath()]]
* @return array test data
*/
public function findRealPathDataProvider()
{
return [
[
'/linux/absolute/path',
'/linux/absolute/path',
],
[
'/linux/up/../path',
'/linux/path',
],
[
'/linux/twice/up/../../path',
'/linux/path',
],
[
'/linux/../mix/up/../path',
'/mix/path',
],
[
'C:\\windows\\absolute\\path',
'C:\\windows\\absolute\\path',
],
[
'C:\\windows\\up\\..\\path',
'C:\\windows\\path',
],
];
}
/**
* @dataProvider findRealPathDataProvider
*
* @param string $sourcePath
* @param string $expectedRealPath
*/
public function testFindRealPath($sourcePath, $expectedRealPath)
{
$expectedRealPath = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $expectedRealPath);
$realPath = $this->invokeAssetControllerMethod('findRealPath', [$sourcePath]);
$this->assertEquals($expectedRealPath, $realPath);
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment