Files
Investidor-V2/app/Services/Malware/ArchiveLimitInspector.php
T
nala 1106509116
tests / ci (push) Canceled after 0s
vrsao 2
2026-10-08 14:02:01 +02:00

55 lines
1.7 KiB
PHP

<?php
namespace App\Services\Malware;
final class ArchiveLimitInspector
{
public function inspect(string $path): ?string
{
$stream = @fopen($path, 'rb');
if (! is_resource($stream)) {
return 'archive_inspection_failed';
}
$signature = fread($stream, 4);
fclose($stream);
if (! is_string($signature) || ! in_array($signature, ["PK\x03\x04", "PK\x05\x06", "PK\x07\x08"], true)) {
return null;
}
if (! class_exists(\ZipArchive::class)) {
return 'archive_inspector_unavailable';
}
$archive = new \ZipArchive;
if ($archive->open($path, \ZipArchive::RDONLY) !== true) {
return 'archive_inspection_failed';
}
try {
$maxEntries = max(1, (int) config('services.malware.max_archive_entries', 1000));
$maxExpandedBytes = max(1, (int) config('services.malware.max_decompressed_bytes', 104857600));
if ($archive->numFiles > $maxEntries) {
return 'archive_entry_limit_exceeded';
}
$expandedBytes = 0;
for ($index = 0; $index < $archive->numFiles; $index++) {
$entry = $archive->statIndex($index);
if (! is_array($entry) || $entry['size'] < 0) {
return 'archive_inspection_failed';
}
if ($entry['size'] > $maxExpandedBytes - $expandedBytes) {
return 'archive_decompression_limit';
}
$expandedBytes += $entry['size'];
}
return null;
} finally {
$archive->close();
}
}
}