From 049d445c58cbaccff9965dff926fb3d8a3bbbdc2 Mon Sep 17 00:00:00 2001 From: KnifeLemon Date: Wed, 22 Oct 2025 01:26:54 +0900 Subject: [PATCH] fix: Support file uploads for non-POST HTTP methods (PATCH, PUT, DELETE) --- flight/net/UploadedFile.php | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/flight/net/UploadedFile.php b/flight/net/UploadedFile.php index 2b3947b..07e0af2 100644 --- a/flight/net/UploadedFile.php +++ b/flight/net/UploadedFile.php @@ -114,15 +114,32 @@ class UploadedFile throw new Exception($this->getUploadErrorMessage($this->error)); } + // Check if this is a legitimate uploaded file (POST method uploads) $isUploadedFile = is_uploaded_file($this->tmpName) === true; - if ( - $isUploadedFile === true - && - move_uploaded_file($this->tmpName, $targetPath) === false - ) { - throw new Exception('Cannot move uploaded file'); // @codeCoverageIgnore - } elseif ($isUploadedFile === false && getenv('PHPUNIT_TEST')) { + + if ($isUploadedFile === true) { + // Standard POST upload - use move_uploaded_file for security + if (move_uploaded_file($this->tmpName, $targetPath) === false) { + throw new Exception('Cannot move uploaded file'); // @codeCoverageIgnore + } + } elseif (getenv('PHPUNIT_TEST')) { rename($this->tmpName, $targetPath); + } elseif (file_exists($this->tmpName) === true && is_readable($this->tmpName) === true) { + // Handle non-POST uploads (PATCH, PUT, DELETE) or other valid temp files + // Verify the file is in a valid temp directory for security + $tempDir = sys_get_temp_dir(); + $uploadTmpDir = ini_get('upload_tmp_dir') ?: $tempDir; + + if (strpos(realpath($this->tmpName), realpath($uploadTmpDir)) === 0 || + strpos(realpath($this->tmpName), realpath($tempDir)) === 0) { + if (rename($this->tmpName, $targetPath) === false) { + throw new Exception('Cannot move uploaded file'); + } + } else { + throw new Exception('Invalid temporary file location'); + } + } else { + throw new Exception('Temporary file does not exist or is not readable'); } }