Skip to content

Commit e3475c9

Browse files
committed
fixup! perf(normalization): Optimize path normalization
1 parent 940e5bf commit e3475c9

File tree

1 file changed

+16
-43
lines changed

1 file changed

+16
-43
lines changed

lib/private/Files/Filesystem.php

Lines changed: 16 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ public static function normalizePath($path, $stripTrailingSlash = true, $isAbsol
599599
*/
600600
$path = (string)$path;
601601

602-
if ($path === '' || $path === '/') {
602+
if ($path === '') {
603603
return '/';
604604
}
605605

@@ -608,53 +608,26 @@ public static function normalizePath($path, $stripTrailingSlash = true, $isAbsol
608608
$path = \OC_Util::normalizeUnicode($path);
609609
}
610610

611-
$len = strlen($path);
612-
$out = [];
613-
$outLen = 0;
611+
//add leading slash, if it is already there we strip it anyway
612+
$path = '/' . $path;
614613

615-
// Force leading slash
616-
$out[$outLen++] = '/';
614+
$patterns = [
615+
'#\\\\#s', // no windows style '\\' slashes
616+
'#/\.(/\.)*/#s', // remove '/./'
617+
'#\//+#s', // remove sequence of slashes
618+
'#/\.$#s', // remove trailing '/.'
619+
];
617620

618-
$prev = '/';
619-
$i = 0;
621+
do {
622+
$count = 0;
623+
$path = preg_replace($patterns, '/', $path, -1, $count);
624+
} while ($count > 0);
620625

621-
while ($i < $len) {
622-
$c = $path[$i++];
623-
624-
// Normalize Windows slashes
625-
if ($c === '\\') {
626-
$c = '/';
627-
}
628-
629-
// Collapse multiple slashes
630-
if ($c === '/' && $prev === '/') {
631-
continue;
632-
}
633-
634-
// Handle "/./" and trailing "/."
635-
if ($c === '.' && $prev === '/') {
636-
$next = $i < $len ? $path[$i] : null;
637-
638-
if ($next === '/' || $next === null) {
639-
// Skip "./"
640-
if ($next === '/') {
641-
$i++;
642-
}
643-
continue;
644-
}
645-
}
646-
647-
$out[$outLen++] = $c;
648-
$prev = $c;
626+
//remove trailing slash
627+
if ($stripTrailingSlash && strlen($path) > 1) {
628+
$path = rtrim($path, '/');
649629
}
650630

651-
// Remove trailing slash
652-
if ($stripTrailingSlash && $outLen > 1 && $out[$outLen - 1] === '/') {
653-
array_pop($out);
654-
}
655-
656-
$path = implode('', $out);
657-
658631
return $path;
659632
}
660633

0 commit comments

Comments
 (0)