From 74f05b716059dc2437218baa6f40469014ea4abb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89rycson=20N=C3=B3brega?= Date: Thu, 29 Oct 2026 00:08:36 -0300 Subject: [PATCH] REST API: Remove the temporary file when a raw-body upload fails the multisite size check. `WP_REST_Attachments_Controller::upload_from_data()` writes the request body to a file from `wp_tempnam()` before calling `check_upload_size()`. When that check fails (file too big, not enough upload space, or user over quota), the method returned the error without deleting the file, so every rejected upload left a copy of its body in the temporary directory. Delete the temporary file before returning, as the method already does when `wp_handle_sideload()` fails and as the URL sideload path does for the same check. Fixes #66409. --- .../class-wp-rest-attachments-controller.php | 2 ++ .../rest-api/rest-attachments-controller.php | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php index 1be17d2dffbe0..4732f8ef8bff3 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php @@ -2052,6 +2052,8 @@ protected function upload_from_data( $data, $headers, $time = null ) { $size_check = self::check_upload_size( $file_data ); if ( is_wp_error( $size_check ) ) { + @unlink( $tmpfname ); + return $size_check; } diff --git a/tests/phpunit/tests/rest-api/rest-attachments-controller.php b/tests/phpunit/tests/rest-api/rest-attachments-controller.php index 5ae35d5ee370d..dc97361ded5cc 100644 --- a/tests/phpunit/tests/rest-api/rest-attachments-controller.php +++ b/tests/phpunit/tests/rest-api/rest-attachments-controller.php @@ -2732,6 +2732,28 @@ public function test_create_item_with_data_exceeds_multisite_max_filesize() { $this->assertErrorResponse( 'rest_upload_file_too_big', $response, 400 ); } + /** + * @ticket 66409 + * @group multisite + * @group ms-required + */ + public function test_create_item_with_data_exceeds_multisite_max_filesize_removes_temp_file() { + wp_set_current_user( self::$author_id ); + update_site_option( 'fileupload_maxk', 1 ); + update_site_option( 'upload_space_check_disabled', false ); + + $temp_files = glob( get_temp_dir() . 'canola-*.tmp' ); + + $request = new WP_REST_Request( 'POST', '/wp/v2/media' ); + $request->set_header( 'Content-Type', 'image/jpeg' ); + $request->set_header( 'Content-Disposition', 'attachment; filename=canola.jpg' ); + $request->set_body( file_get_contents( self::$test_file ) ); + + $response = rest_get_server()->dispatch( $request ); + $this->assertErrorResponse( 'rest_upload_file_too_big', $response, 400 ); + $this->assertSame( $temp_files, glob( get_temp_dir() . 'canola-*.tmp' ), 'The temporary file should be removed when the upload is rejected.' ); + } + /** * @ticket 43751 * @group multisite