Skip to content
Snippets Groups Projects
Unverified Commit eac04ada authored by Morris Jobke's avatar Morris Jobke Committed by GitHub
Browse files

Merge pull request #11689 from nextcloud/performance/normalizePath

Move normalizePath to regexes instead of looping
parents 1dbd7172 d5bf2c45
No related branches found
No related tags found
No related merge requests found
...@@ -812,7 +812,7 @@ class Filesystem { ...@@ -812,7 +812,7 @@ class Filesystem {
return self::$normalizedPathCache[$cacheKey]; return self::$normalizedPathCache[$cacheKey];
} }
if ($path == '') { if ($path === '') {
return '/'; return '/';
} }
...@@ -821,38 +821,29 @@ class Filesystem { ...@@ -821,38 +821,29 @@ class Filesystem {
$path = \OC_Util::normalizeUnicode($path); $path = \OC_Util::normalizeUnicode($path);
} }
//no windows style slashes //add leading slash, if it is already there we strip it anyway
$path = str_replace('\\', '/', $path); $path = '/' . $path;
//add leading slash $patterns = [
if ($path[0] !== '/') { '/\\\\/s', // no windows style slashes
$path = '/' . $path; '/\/\.(\/\.)?\//s', // remove '/./'
} '/\/{2,}/s', // remove squence of slashes
'/\/\.$/s', // remove trailing /.
];
// remove '/./' do {
// ugly, but str_replace() can't replace them all in one go $count = 0;
// as the replacement itself is part of the search string $path = preg_replace($patterns, '/', $path, -1, $count);
// which will only be found during the next iteration } while ($count > 0);
while (strpos($path, '/./') !== false) {
$path = str_replace('/./', '/', $path);
}
// remove sequences of slashes
$path = preg_replace('#/{2,}#', '/', $path);
//remove trailing slash //remove trailing slash
if ($stripTrailingSlash and strlen($path) > 1) { if ($stripTrailingSlash && strlen($path) > 1) {
$path = rtrim($path, '/'); $path = rtrim($path, '/');
} }
// remove trailing '/.' self::$normalizedPathCache[$cacheKey] = $path;
if (substr($path, -2) == '/.') {
$path = substr($path, 0, -2);
}
$normalizedPath = $path;
self::$normalizedPathCache[$cacheKey] = $normalizedPath;
return $normalizedPath; return $path;
} }
/** /**
......
...@@ -115,73 +115,80 @@ class FilesystemTest extends \Test\TestCase { ...@@ -115,73 +115,80 @@ class FilesystemTest extends \Test\TestCase {
} }
public function normalizePathData() { public function normalizePathData() {
return array( return [
array('/', ''), ['/', ''],
array('/', '/'), ['/', '/'],
array('/', '//'), ['/', '//'],
array('/', '/', false), ['/', '/', false],
array('/', '//', false), ['/', '//', false],
array('/path', '/path/'), ['/path', '/path/'],
array('/path/', '/path/', false), ['/path/', '/path/', false],
array('/path', 'path'), ['/path', 'path'],
array('/foo/bar', '/foo//bar/'), ['/foo/bar', '/foo//bar/'],
array('/foo/bar/', '/foo//bar/', false), ['/foo/bar/', '/foo//bar/', false],
array('/foo/bar', '/foo////bar'), ['/foo/bar', '/foo////bar'],
array('/foo/bar', '/foo/////bar'), ['/foo/bar', '/foo/////bar'],
array('/foo/bar', '/foo/bar/.'), ['/foo/bar', '/foo/bar/.'],
array('/foo/bar', '/foo/bar/./'), ['/foo/bar', '/foo/bar/./'],
array('/foo/bar/', '/foo/bar/./', false), ['/foo/bar/', '/foo/bar/./', false],
array('/foo/bar', '/foo/bar/./.'), ['/foo/bar', '/foo/bar/./.'],
array('/foo/bar', '/foo/bar/././'), ['/foo/bar', '/foo/bar/././'],
array('/foo/bar/', '/foo/bar/././', false), ['/foo/bar/', '/foo/bar/././', false],
array('/foo/bar', '/foo/./bar/'), ['/foo/bar', '/foo/./bar/'],
array('/foo/bar/', '/foo/./bar/', false), ['/foo/bar/', '/foo/./bar/', false],
array('/foo/.bar', '/foo/.bar/'), ['/foo/.bar', '/foo/.bar/'],
array('/foo/.bar/', '/foo/.bar/', false), ['/foo/.bar/', '/foo/.bar/', false],
array('/foo/.bar/tee', '/foo/.bar/tee'), ['/foo/.bar/tee', '/foo/.bar/tee'],
['/foo/bar', '/.///././//./foo/.///././//./bar/./././.'],
['/foo/bar/', '/.///././//./foo/.///././//./bar/./././.', false],
['/foo/bar', '/.///././//./foo/.///././//./bar/././././'],
['/foo/bar/', '/.///././//./foo/.///././//./bar/././././', false],
// Windows paths // Windows paths
array('/', ''), ['/', ''],
array('/', '\\'), ['/', '\\'],
array('/', '\\', false), ['/', '\\', false],
array('/', '\\\\'), ['/', '\\\\'],
array('/', '\\\\', false), ['/', '\\\\', false],
array('/path', '\\path'), ['/path', '\\path'],
array('/path', '\\path', false), ['/path', '\\path', false],
array('/path', '\\path\\'), ['/path', '\\path\\'],
array('/path/', '\\path\\', false), ['/path/', '\\path\\', false],
array('/foo/bar', '\\foo\\\\bar\\'), ['/foo/bar', '\\foo\\\\bar\\'],
array('/foo/bar/', '\\foo\\\\bar\\', false), ['/foo/bar/', '\\foo\\\\bar\\', false],
array('/foo/bar', '\\foo\\\\\\\\bar'), ['/foo/bar', '\\foo\\\\\\\\bar'],
array('/foo/bar', '\\foo\\\\\\\\\\bar'), ['/foo/bar', '\\foo\\\\\\\\\\bar'],
array('/foo/bar', '\\foo\\bar\\.'), ['/foo/bar', '\\foo\\bar\\.'],
array('/foo/bar', '\\foo\\bar\\.\\'), ['/foo/bar', '\\foo\\bar\\.\\'],
array('/foo/bar/', '\\foo\\bar\\.\\', false), ['/foo/bar/', '\\foo\\bar\\.\\', false],
array('/foo/bar', '\\foo\\bar\\.\\.'), ['/foo/bar', '\\foo\\bar\\.\\.'],
array('/foo/bar', '\\foo\\bar\\.\\.\\'), ['/foo/bar', '\\foo\\bar\\.\\.\\'],
array('/foo/bar/', '\\foo\\bar\\.\\.\\', false), ['/foo/bar/', '\\foo\\bar\\.\\.\\', false],
array('/foo/bar', '\\foo\\.\\bar\\'), ['/foo/bar', '\\foo\\.\\bar\\'],
array('/foo/bar/', '\\foo\\.\\bar\\', false), ['/foo/bar/', '\\foo\\.\\bar\\', false],
array('/foo/.bar', '\\foo\\.bar\\'), ['/foo/.bar', '\\foo\\.bar\\'],
array('/foo/.bar/', '\\foo\\.bar\\', false), ['/foo/.bar/', '\\foo\\.bar\\', false],
array('/foo/.bar/tee', '\\foo\\.bar\\tee'), ['/foo/.bar/tee', '\\foo\\.bar\\tee'],
// Absolute windows paths NOT marked as absolute // Absolute windows paths NOT marked as absolute
array('/C:', 'C:\\'), ['/C:', 'C:\\'],
array('/C:/', 'C:\\', false), ['/C:/', 'C:\\', false],
array('/C:/tests', 'C:\\tests'), ['/C:/tests', 'C:\\tests'],
array('/C:/tests', 'C:\\tests', false), ['/C:/tests', 'C:\\tests', false],
array('/C:/tests', 'C:\\tests\\'), ['/C:/tests', 'C:\\tests\\'],
array('/C:/tests/', 'C:\\tests\\', false), ['/C:/tests/', 'C:\\tests\\', false],
['/C:/tests/bar', 'C:\\tests\\.\\.\\bar'],
['/C:/tests/bar/', 'C:\\tests\\.\\.\\bar\\.\\', false],
// normalize does not resolve '..' (by design) // normalize does not resolve '..' (by design)
array('/foo/..', '/foo/../'), ['/foo/..', '/foo/../'],
array('/foo/..', '\\foo\\..\\'), ['/foo/..', '\\foo\\..\\'],
); ];
} }
/** /**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment