mirror of
https://github.com/getgrav/grav.git
synced 2026-06-14 21:30:24 +02:00
Better Utils::normalizePath() logic #2216
This commit is contained in:
@@ -1,3 +1,9 @@
|
||||
# v1.6.4
|
||||
## mm/dd/2019
|
||||
|
||||
1. [](#bugfix)
|
||||
* Better logic in `Utils::normalizePath` to handle externals properly [#2216](https://github.com/getgrav/grav/issues/2216)
|
||||
|
||||
# v1.6.3
|
||||
## 04/12/2019
|
||||
|
||||
|
||||
@@ -20,7 +20,9 @@ abstract class Utils
|
||||
{
|
||||
protected static $nonces = [];
|
||||
|
||||
protected const ROOTURL_REGEX = '{^(\/*)}';
|
||||
protected const ROOTURL_REGEX = '{^((?:http[s]?:\/\/[^\/]+)|(?:\/\/[^\/]+))(.*)}';
|
||||
|
||||
// ^((?:http[s]?:)?[\/]?(?:\/))
|
||||
|
||||
/**
|
||||
* Simple helper method to make getting a Grav URL easier
|
||||
@@ -784,31 +786,43 @@ abstract class Utils
|
||||
*/
|
||||
public static function normalizePath($path)
|
||||
{
|
||||
|
||||
if (Uri::isExternal($path)) {
|
||||
return $path;
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = Grav::instance()['locator'];
|
||||
if ($locator->isStream($path)) {
|
||||
$path = $locator->findResource($path);
|
||||
}
|
||||
|
||||
$root = '';
|
||||
preg_match(self::ROOTURL_REGEX, $path, $matches);
|
||||
if ($matches) {
|
||||
$root = $matches[0];
|
||||
$root = $matches[1];
|
||||
$path = $matches[2];
|
||||
}
|
||||
|
||||
$clean_path = static::replaceFirstOccurrence($root, '', $path);
|
||||
$segments = explode('/', trim($clean_path, '/'));
|
||||
$ret = [];
|
||||
foreach ($segments as $segment) {
|
||||
if (($segment === '.') || $segment === '') {
|
||||
continue;
|
||||
}
|
||||
if ($segment === '..') {
|
||||
array_pop($ret);
|
||||
} else {
|
||||
$ret[] = $segment;
|
||||
}
|
||||
if (Utils::startsWith($path,'/')) {
|
||||
$root .= '/';
|
||||
$path = ltrim($path, '/');
|
||||
}
|
||||
$normalized = $root . implode('/', $ret);
|
||||
|
||||
// $path = ltrim(static::replaceFirstOccurrence($root, '', $path), '/');
|
||||
|
||||
if (Utils::contains($path, '..')) {
|
||||
$segments = explode('/', trim($path, '/'));
|
||||
$ret = [];
|
||||
foreach ($segments as $segment) {
|
||||
if (($segment === '.') || $segment === '') {
|
||||
continue;
|
||||
}
|
||||
if ($segment === '..') {
|
||||
array_pop($ret);
|
||||
} else {
|
||||
$ret[] = $segment;
|
||||
}
|
||||
}
|
||||
$path = implode('/', $ret);
|
||||
}
|
||||
|
||||
$normalized = $root . $path;
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
|
||||
@@ -224,9 +224,19 @@ class UtilsTest extends \Codeception\TestCase\Test
|
||||
$this->assertEquals('test', Utils::normalizePath('../test'));
|
||||
$this->assertEquals('/test', Utils::normalizePath('/../test'));
|
||||
$this->assertEquals('/test2', Utils::normalizePath('/test/../test2'));
|
||||
$this->assertEquals('/test/test2', Utils::normalizePath('/test/./test2'));
|
||||
$this->assertEquals('/test3', Utils::normalizePath('/test/../test2/../test3'));
|
||||
|
||||
$this->assertEquals('//cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/leaflet.awesome-markers.css', Utils::normalizePath('//cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/leaflet.awesome-markers.css'));
|
||||
$this->assertEquals('//use.fontawesome.com/releases/v5.8.1/css/all.css', Utils::normalizePath('//use.fontawesome.com/releases/v5.8.1/css/all.css'));
|
||||
$this->assertEquals('//use.fontawesome.com/releases/v5.8.1/webfonts/fa-brands-400.eot', Utils::normalizePath('//use.fontawesome.com/releases/v5.8.1/css/../webfonts/fa-brands-400.eot'));
|
||||
|
||||
$this->assertEquals('http://cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/leaflet.awesome-markers.css', Utils::normalizePath('http://cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/leaflet.awesome-markers.css'));
|
||||
$this->assertEquals('http://use.fontawesome.com/releases/v5.8.1/css/all.css', Utils::normalizePath('http://use.fontawesome.com/releases/v5.8.1/css/all.css'));
|
||||
$this->assertEquals('http://use.fontawesome.com/releases/v5.8.1/webfonts/fa-brands-400.eot', Utils::normalizePath('http://use.fontawesome.com/releases/v5.8.1/css/../webfonts/fa-brands-400.eot'));
|
||||
|
||||
$this->assertEquals('https://cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/leaflet.awesome-markers.css', Utils::normalizePath('https://cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/leaflet.awesome-markers.css'));
|
||||
$this->assertEquals('//something.com/../test/test2', Utils::normalizePath('//something.com/../test/test2'));
|
||||
$this->assertEquals('https://use.fontawesome.com/releases/v5.8.1/css/all.css', Utils::normalizePath('https://use.fontawesome.com/releases/v5.8.1/css/all.css'));
|
||||
$this->assertEquals('https://use.fontawesome.com/releases/v5.8.1/webfonts/fa-brands-400.eot', Utils::normalizePath('https://use.fontawesome.com/releases/v5.8.1/css/../webfonts/fa-brands-400.eot'));
|
||||
}
|
||||
|
||||
public function testIsFunctionDisabled()
|
||||
|
||||
Reference in New Issue
Block a user