Skip to content

Commit 0b23ff7

Browse files
jbagsikcursoragent
andcommitted
Deduplicate unsafe ZIP entry rejection in SafeZipExtractor
Extract reject(): never helper so the shared throw message lives in one place after the assertEntryIsSafe complexity refactor. Refs mooxphp/verapdf#7 Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent a5cc73d commit 0b23ff7

1 file changed

Lines changed: 12 additions & 4 deletions

File tree

packages/verapdf/src/Support/SafeZipExtractor.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public static function extract(string $zipPath, string $targetDir): void
5151
private static function assertEntryIsSafe(ZipArchive $zip, int $index, string $entryName, string $targetDir): void
5252
{
5353
if (self::isSymlinkEntry($zip, $index)) {
54-
throw new RuntimeException("Refusing to extract unsafe ZIP entry: {$entryName}");
54+
self::reject($entryName);
5555
}
5656

5757
$normalized = str_replace('\\', '/', $entryName);
@@ -64,15 +64,15 @@ private static function assertEntryIsSafe(ZipArchive $zip, int $index, string $e
6464
private static function assertPathIsRelative(string $entryName, string $normalized): void
6565
{
6666
if ($normalized === '' || str_starts_with($normalized, '/') || preg_match('#^[A-Za-z]:/#', $normalized) === 1) {
67-
throw new RuntimeException("Refusing to extract unsafe ZIP entry: {$entryName}");
67+
self::reject($entryName);
6868
}
6969
}
7070

7171
private static function assertPathHasNoUnsafeSegments(string $entryName, string $normalized): void
7272
{
7373
foreach (explode('/', rtrim($normalized, '/')) as $segment) {
7474
if ($segment === '' || $segment === '.' || $segment === '..') {
75-
throw new RuntimeException("Refusing to extract unsafe ZIP entry: {$entryName}");
75+
self::reject($entryName);
7676
}
7777
}
7878
}
@@ -83,10 +83,18 @@ private static function assertPathStaysUnderTarget(string $entryName, string $no
8383
$destination = $targetRoot.'/'.ltrim($normalized, '/');
8484

8585
if ($destination !== $targetRoot && ! str_starts_with($destination, $targetRoot.'/')) {
86-
throw new RuntimeException("Refusing to extract unsafe ZIP entry: {$entryName}");
86+
self::reject($entryName);
8787
}
8888
}
8989

90+
/**
91+
* @throws RuntimeException
92+
*/
93+
private static function reject(string $entryName): never
94+
{
95+
throw new RuntimeException("Refusing to extract unsafe ZIP entry: {$entryName}");
96+
}
97+
9098
private static function isSymlinkEntry(ZipArchive $zip, int $index): bool
9199
{
92100
$opsys = 0;

0 commit comments

Comments
 (0)