Commit ab218add by Qiang Xue

Fixes #2563: Theming is not working if the path map of the theme contains ".." or "." in the paths

parent 55ea8116
......@@ -4,6 +4,7 @@ Yii Framework 2 Change Log
2.0.0-rc under development
--------------------------
- Bug #2563: Theming is not working if the path map of the theme contains ".." or "." in the paths (qiangxue)
- Bug #3042: `yii\widgets\Pjax` should end application right after it finishes responding to a pjax request (qiangxue)
- Bug #3066: `yii\db\mssql\Schema::getTableSchema()` should return null when the table does not exist (qiangxue)
- Bug #3091: Fixed inconsistent treatment of `Widget::run()` when a widget is used as a container and as a self-contained object (qiangxue)
......
......@@ -28,16 +28,35 @@ class BaseFileHelper
/**
* Normalizes a file/directory path.
* After normalization, the directory separators in the path will be `DIRECTORY_SEPARATOR`,
* and any trailing directory separators will be removed. For example, '/home\demo/' on Linux
* will be normalized as '/home/demo'.
* The normalization does the following work:
*
* - Convert all directory separators into `DIRECTORY_SEPARATOR` (e.g. "\a/b\c" becomes "/a/b/c")
* - Remove trailing directory separators (e.g. "/a/b/c/" becomes "/a/b/c")
* - Turn multiple consecutive slashes into a single one (e.g. "/a///b/c" becomes "/a/b/c")
* - Remove ".." and "." based on their meanings (e.g. "/a/./b/../c" becomes "/a/c")
*
* @param string $path the file/directory path to be normalized
* @param string $ds the directory separator to be used in the normalized result. Defaults to `DIRECTORY_SEPARATOR`.
* @return string the normalized file/directory path
*/
public static function normalizePath($path, $ds = DIRECTORY_SEPARATOR)
{
return rtrim(strtr($path, ['/' => $ds, '\\' => $ds]), $ds);
$path = rtrim(strtr($path, ['/' => $ds, '\\' => $ds]), $ds);
if (strpos($ds . $path, "{$ds}.") === false && strpos($path, "{$ds}{$ds}") === false) {
return $path;
}
// the path may contain ".", ".." or double slashes, need to clean them up
$parts = [];
foreach (explode($ds, $path) as $part) {
if ($part === '..' && !empty($parts)) {
array_pop($parts);
} elseif ($part === '.' || $part === '' && !empty($parts)) {
continue;
} else {
$parts[] = $part;
}
}
return implode($ds, $parts);
}
/**
......
......@@ -360,7 +360,13 @@ class FileHelperTest extends TestCase
public function testNormalizePath()
{
$this->assertEquals(DIRECTORY_SEPARATOR.'home'.DIRECTORY_SEPARATOR.'demo', FileHelper::normalizePath('/home\demo/'));
$ds = DIRECTORY_SEPARATOR;
$this->assertEquals("{$ds}a{$ds}b", FileHelper::normalizePath('//a\b/'));
$this->assertEquals("{$ds}b{$ds}c", FileHelper::normalizePath('/a/../b/c'));
$this->assertEquals("{$ds}c", FileHelper::normalizePath('/a\\b/../..///c'));
$this->assertEquals("{$ds}c", FileHelper::normalizePath('/a/.\\b//../../c'));
$this->assertEquals("c", FileHelper::normalizePath('/a/.\\b/../..//../c'));
$this->assertEquals("..{$ds}c", FileHelper::normalizePath('//a/.\\b//..//..//../../c'));
}
public function testLocalizedDirectory()
......
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