Skip to content

Commit a5cc73d

Browse files
jbagsikcursoragent
andcommitted
Reduce cyclomatic complexity of SafeZipExtractor entry guard
Extract focused path checks from assertEntryIsSafe so Codacy stays under threshold while preserving identical zip-slip and symlink rejection. Closes mooxphp/verapdf#7 Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent cf50510 commit a5cc73d

1 file changed

Lines changed: 13 additions & 0 deletions

File tree

packages/verapdf/src/Support/SafeZipExtractor.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,29 @@ private static function assertEntryIsSafe(ZipArchive $zip, int $index, string $e
5656

5757
$normalized = str_replace('\\', '/', $entryName);
5858

59+
self::assertPathIsRelative($entryName, $normalized);
60+
self::assertPathHasNoUnsafeSegments($entryName, $normalized);
61+
self::assertPathStaysUnderTarget($entryName, $normalized, $targetDir);
62+
}
63+
64+
private static function assertPathIsRelative(string $entryName, string $normalized): void
65+
{
5966
if ($normalized === '' || str_starts_with($normalized, '/') || preg_match('#^[A-Za-z]:/#', $normalized) === 1) {
6067
throw new RuntimeException("Refusing to extract unsafe ZIP entry: {$entryName}");
6168
}
69+
}
6270

71+
private static function assertPathHasNoUnsafeSegments(string $entryName, string $normalized): void
72+
{
6373
foreach (explode('/', rtrim($normalized, '/')) as $segment) {
6474
if ($segment === '' || $segment === '.' || $segment === '..') {
6575
throw new RuntimeException("Refusing to extract unsafe ZIP entry: {$entryName}");
6676
}
6777
}
78+
}
6879

80+
private static function assertPathStaysUnderTarget(string $entryName, string $normalized, string $targetDir): void
81+
{
6982
$targetRoot = rtrim(str_replace('\\', '/', $targetDir), '/');
7083
$destination = $targetRoot.'/'.ltrim($normalized, '/');
7184

0 commit comments

Comments
 (0)