Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 14 additions & 16 deletions src/wp-includes/media.php
Original file line number Diff line number Diff line change
Expand Up @@ -6885,9 +6885,9 @@ function wp_get_media_library_upload_settings(): array {
* browser honors Document-Isolation-Policy: without isolation the page never
* becomes cross-origin isolated, the script would no-op, and the whole
* wp-upload-media dependency chain would be loaded for nothing. The same
* goes for a screen wp_set_up_cross_origin_isolation() did not isolate,
* such as the Customizer or the Site Icon picker: the media frame loads
* there too, but its uploads stay on the classic path.
* goes for a screen wp_send_document_isolation_policy_header() did not
* isolate, such as the Customizer or the Site Icon picker: the media frame
* loads there too, but its uploads stay on the classic path.
*
* The screen script self-guards at runtime too: when the browser turns out
* not to be isolated or lacks client-side media support, it no-ops and the
Expand Down Expand Up @@ -6945,7 +6945,8 @@ function _wp_enqueue_media_upload_pipeline_script( string $handle ): void {
* Covers every `wp.media` frame that uploads through `wp.Uploader`: the
* Media Library grid and the media modal the block editor, the site editor
* and the block widgets screen open. wp_enqueue_media() calls this on any
* screen that was cross-origin isolated, so it rarely needs calling directly.
* screen wp_send_document_isolation_policy_header() isolated, so it rarely
* needs calling directly.
*
* @since 7.2.0
*/
Expand All @@ -6972,6 +6973,9 @@ function wp_enqueue_media_new_upload(): void {
* Forcing `crossorigin="anonymous"` would turn those into CORS requests
* and break any resource served without `Access-Control-Allow-Origin`.
*
* Sending the header also opts the screen's media frames into client-side
* uploads, so call this before wp_enqueue_media() runs.
*
* @since 7.2.0
*
* @global bool $_wp_cross_origin_isolated Whether the Document-Isolation-Policy header was sent.
Expand All @@ -6996,14 +7000,15 @@ function wp_send_document_isolation_policy_header(): bool {
/**
* Whether the current request has been set up for cross-origin isolation.
*
* True once wp_set_up_cross_origin_isolation() has sent the
* True once wp_send_document_isolation_policy_header() has sent the
* Document-Isolation-Policy header for the screen being rendered, which is
* what lets scripts that need a cross-origin isolated page, such as the
* client-side media upload integration, decide whether to load at all.
*
* A plugin can isolate a screen on its own by sending the header directly,
* as the Gutenberg plugin does on the block editor screens, so a header
* already queued for the response counts too.
* A header a plugin sends itself does not count, since the plugin may
* isolate its screen for reasons of its own. To run the client-side
* pipeline on a screen core does not isolate, call
* wp_send_document_isolation_policy_header() before wp_enqueue_media().
*
* @since 7.2.0
*
Expand All @@ -7014,13 +7019,6 @@ function wp_send_document_isolation_policy_header(): bool {
function wp_is_cross_origin_isolated_request(): bool {
global $_wp_cross_origin_isolated;

if ( true === $_wp_cross_origin_isolated ) {
return true;
}

return array_any(
headers_list(),
fn( $header ) => 0 === stripos( $header, 'Document-Isolation-Policy:' )
);
return true === $_wp_cross_origin_isolated;
}

27 changes: 27 additions & 0 deletions tests/phpunit/tests/media/wpCrossOriginIsolation.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* @group media
* @covers ::wp_set_up_cross_origin_isolation
* @covers ::wp_send_document_isolation_policy_header
* @covers ::wp_is_cross_origin_isolated_request
* @covers ::wp_is_client_side_media_processing_enabled
*/
class Tests_Media_wpCrossOriginIsolation extends WP_UnitTestCase {
Expand Down Expand Up @@ -121,6 +122,32 @@ public function test_sends_header_for_chrome_137() {
$this->assertTrue( wp_send_document_isolation_policy_header(), 'The Document-Isolation-Policy header should be sent for Chrome 137.' );
}

/**
* @ticket 66490
*
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function test_sending_header_marks_request_isolated(): void {
$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36';

$this->assertFalse( wp_is_cross_origin_isolated_request(), 'The request should not be isolated before the header is sent.' );

wp_send_document_isolation_policy_header();

$this->assertTrue( wp_is_cross_origin_isolated_request(), 'The request should be isolated once core sends the header.' );
}

/**
* @ticket 66490
*/
public function test_request_not_isolated_when_header_not_sent(): void {
$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Windows NT 10.0; rv:128.0) Gecko/20100101 Firefox/128.0';

$this->assertFalse( wp_send_document_isolation_policy_header() );
$this->assertFalse( wp_is_cross_origin_isolated_request(), 'The request should not be isolated when the header was not sent.' );
}

/**
* @ticket 64766
*/
Expand Down
8 changes: 4 additions & 4 deletions tests/phpunit/tests/media/wpEnqueueMediaFrameUpload.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public function set_up() {
$this->original_wp_scripts = $wp_scripts;
$wp_scripts = new WP_Scripts();

// The screen was cross-origin isolated, as wp_set_up_cross_origin_isolation() records.
// The screen was cross-origin isolated, as wp_send_document_isolation_policy_header() records.
$GLOBALS['_wp_cross_origin_isolated'] = true;
}

Expand Down Expand Up @@ -91,9 +91,9 @@ public function test_script_enqueued() {
}

/**
* A screen wp_set_up_cross_origin_isolation() did not isolate cannot run
* the pipeline, so the media frame there keeps its classic uploads and
* does not download the pipeline bundles.
* A screen wp_send_document_isolation_policy_header() did not isolate
* cannot run the pipeline, so the media frame there keeps its classic
* uploads and does not download the pipeline bundles.
*
* @ticket 65661
*/
Expand Down
2 changes: 1 addition & 1 deletion tests/phpunit/tests/media/wpEnqueueMediaNewUpload.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public function set_up() {
$this->original_wp_scripts = $wp_scripts;
$wp_scripts = new WP_Scripts();

// The screen was cross-origin isolated, as wp_set_up_cross_origin_isolation() records.
// The screen was cross-origin isolated, as wp_send_document_isolation_policy_header() records.
$GLOBALS['_wp_cross_origin_isolated'] = true;
}

Expand Down
Loading