From 94b14596d7ff3c88bc0574b1ce790d61029cdf1f Mon Sep 17 00:00:00 2001 From: DariusIII Date: Tue, 4 Aug 2026 15:23:41 +0200 Subject: [PATCH] Fix issue with sizes --- .../ReleaseFileManager.php | 44 ++++++++++++++++++- ...tionalProcessingReleaseFileManagerTest.php | 44 +++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/app/Services/AdditionalProcessing/ReleaseFileManager.php b/app/Services/AdditionalProcessing/ReleaseFileManager.php index 89e58a72e..7aa2815f5 100644 --- a/app/Services/AdditionalProcessing/ReleaseFileManager.php +++ b/app/Services/AdditionalProcessing/ReleaseFileManager.php @@ -100,6 +100,17 @@ class ReleaseFileManager return false; } + $size = $this->normalizeFileSize($file['size'] ?? 0); + if ($size === null) { + Log::warning('Skipping release file with invalid size metadata.', [ + 'release_id' => $context->release->id, + 'name' => $file['name'], + 'size_type' => get_debug_type($file['size'] ?? 0), + ]); + + return false; + } + // Increment total file info count $context->totalFileInfo++; @@ -112,7 +123,7 @@ class ReleaseFileManager $context, $context->release->id, $file['name'], - $file['size'] ?? 0, + $size, $file['date'] ?? now(), $file['pass'] ?? 0, '', @@ -726,6 +737,37 @@ class ReleaseFileManager return Carbon::createFromTimestamp($createdTime, date_default_timezone_get())->format('Y-m-d H:i:s'); } + private function normalizeFileSize(mixed $size): ?int + { + if (is_int($size)) { + return $size >= 0 ? $size : null; + } + + if (is_float($size)) { + return is_finite($size) && $size >= 0 && $size < PHP_INT_MAX + ? (int) $size + : null; + } + + if (! is_string($size) || preg_match('/^\d+$/D', $size) !== 1) { + return null; + } + + $normalizedSize = ltrim($size, '0'); + if ($normalizedSize === '') { + return 0; + } + + $maximumSize = (string) PHP_INT_MAX; + if (strlen($normalizedSize) > strlen($maximumSize) + || (strlen($normalizedSize) === strlen($maximumSize) && strcmp($normalizedSize, $maximumSize) > 0) + ) { + return null; + } + + return (int) $normalizedSize; + } + private function releaseHasNzbSplitWrapper(Release $release): bool { $name = (string) ($release->name ?? ''); diff --git a/tests/Feature/AdditionalProcessingReleaseFileManagerTest.php b/tests/Feature/AdditionalProcessingReleaseFileManagerTest.php index 3d743fb76..a0ab26755 100644 --- a/tests/Feature/AdditionalProcessingReleaseFileManagerTest.php +++ b/tests/Feature/AdditionalProcessingReleaseFileManagerTest.php @@ -17,6 +17,7 @@ use Illuminate\Contracts\Console\Kernel; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\File; +use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Schema; use Mockery; use PDO; @@ -155,6 +156,49 @@ class AdditionalProcessingReleaseFileManagerTest extends TestCase $this->assertSame(1, DB::table('par_hashes')->count()); } + public function test_float_release_file_size_is_normalized_before_queueing(): void + { + DB::table('releases')->insert($this->releaseRow()); + + Search::shouldReceive('updateRelease')->once()->with(1); + + $manager = $this->makeManager(); + $context = new ReleaseProcessingContext(Release::query()->findOrFail(1)); + + $this->assertTrue($manager->addFileInfo([ + 'name' => 'Example.Movie.2026.mkv', + 'size' => 1024.0, + 'date' => 1_788_600_000, + ], $context, '\\.(?:par2|sfv|nzb)')); + + $manager->finalizeRelease($context, false); + + $this->assertSame(1024, DB::table('release_files')->value('size')); + } + + public function test_invalid_release_file_sizes_are_rejected(): void + { + DB::table('releases')->insert($this->releaseRow()); + + Log::shouldReceive('warning') + ->times(4) + ->with('Skipping release file with invalid size metadata.', Mockery::type('array')); + + $manager = $this->makeManager(); + $context = new ReleaseProcessingContext(Release::query()->findOrFail(1)); + $invalidSizes = [-1, INF, PHP_INT_MAX + 1.0, 'not-numeric']; + + foreach ($invalidSizes as $index => $invalidSize) { + $this->assertFalse($manager->addFileInfo([ + 'name' => "Invalid.Size.{$index}.mkv", + 'size' => $invalidSize, + ], $context, '\\.(?:par2|sfv|nzb)')); + } + + $this->assertSame(0, $context->totalFileInfo); + $this->assertSame(0, $context->addedFileInfo); + } + public function test_finalize_recognizes_webp_preview_and_sample_without_moving_them(): void { DB::table('releases')->insert($this->releaseRow());