Skip to content

Add crossorigin="anonymous" to IMG elements after Gutenberg core change - #18

Merged
adamsilverstein merged 1 commit into
mainfrom
copilot/ensure-images-use-cors-attribute
Jul 16, 2026
Merged

adamsilverstein merged 1 commit into
mainfrom
copilot/ensure-images-use-cors-attribute

Conversation

Copilot AI commented Mar 18, 2026 •

Copy link
Copy Markdown
Contributor

Gutenberg is removing img from the elements mutated by wp_add_crossorigin_attributes() / gutenberg_add_crossorigin_attributes() (gutenberg#76618). This plugin's COEP/COOP mode still requires crossorigin="anonymous" on images for cross-origin isolation to work on Firefox/Safari.

Changes

  • includes/cross-origin-isolation.php: Add csme_add_crossorigin_to_images() — an IMG-only implementation using WP_HTML_Tag_Processor that adds crossorigin="anonymous" to cross-origin <img> elements. Other elements (AUDIO, LINK, SCRIPT, VIDEO, SOURCE) are still handled by core/Gutenberg.
  • csme_start_coep_coop_output_buffer(): Now first delegates to wp_add_crossorigin_attributes() / gutenberg_add_crossorigin_attributes() for non-IMG elements, then calls csme_add_crossorigin_to_images() to add back IMG support.
  • tests/Test_Add_Crossorigin_Attributes.php: 9 test cases covering cross-origin/same-origin IMG URLs, relative paths, existing attributes, confirmation that non-IMG tags are not modified, and edge cases.
// Before: dependent on core functions that may remove img support
if ( function_exists( 'wp_add_crossorigin_attributes' ) ) {
    return wp_add_crossorigin_attributes( $output );
}

// After: core handles other elements, plugin adds back IMG support
if ( function_exists( 'wp_add_crossorigin_attributes' ) ) {
    $output = wp_add_crossorigin_attributes( $output );
}
return csme_add_crossorigin_to_images( $output );
Original prompt

This section details on the original issue you should resolve

<issue_title>Ensure images use crossorigin="anonymous" after Gutenberg core change</issue_title>
<issue_description>Describe the feature

Update the codebase to ensure that images handled by this project are assigned the correct crossorigin="anonymous" attribute. This is necessary because support for this attribute on <img> elements is being removed from the core codebase in Gutenberg (see: WordPress/gutenberg#76618).

Use case

Projects that relied on Gutenberg to add crossorigin to <img> tags will lose this functionality once the change in WordPress/gutenberg#76618 lands. This may impact media usage, especially when using features/applications that require proper CORS headers for images (such as canvas manipulation or using images across domains).

Additional context

<agent_instructions>make a plan first. see wp_add_crossorigin_attributes for the best approach to adding this.</agent_instructions>

Comments on the Issue (you are @copilot in this section)


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Summary by CodeRabbit

Release Notes

  • Improvements

    • Enhanced cross-origin resource handling to automatically add appropriate security attributes to external media files (images, scripts, videos, links).
    • Improved detection and processing of cross-origin versus same-origin resources, with better handling for nested media elements.
  • Tests

    • Added comprehensive test coverage for cross-origin resource security handling.

Copilot AI changed the title [WIP] Update images to use crossorigin="anonymous" attribute Add plugin-owned crossorigin="anonymous" attribute injection Mar 18, 2026
Copilot AI requested a review from adamsilverstein March 18, 2026 17:54
@adamsilverstein

Copy link
Copy Markdown
Owner

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Mar 19, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Mar 19, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a0230b26-0b3a-44e3-9831-05654849b5b3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR refactors cross-origin attribute handling by introducing a new public function csme_add_crossorigin_attributes($html) that uses WP_HTML_Tag_Processor to scan and inject crossorigin="anonymous" on external resource tags (IMG, SCRIPT, LINK, VIDEO, AUDIO, SOURCE), replacing previous inline delegation to Gutenberg functions.

Changes

Cohort / File(s) Summary
Cross-Origin Attribute Handler
includes/cross-origin-isolation.php
Implements new csme_add_crossorigin_attributes($html) function using WP_HTML_Tag_Processor to identify and inject crossorigin attributes on external resources. Includes fallback to core/Gutenberg implementations when tag processor unavailable. Special handling for SOURCE tags via parent bookmark.
Comprehensive Test Suite
tests/Test_Add_Crossorigin_Attributes.php
Adds 12 PHPUnit test methods covering crossorigin injection for various tag types (img, script, link, video), same-origin/relative URL exclusions, existing attribute preservation, source tag parent handling, and multi-element scenarios.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

  • #6: Main PR implementation that adds the csme_add_crossorigin_attributes function and corresponding PHPUnit test infrastructure targeting the same functionality.

Poem

🐰 A function hops through HTML so fine,
Spotting images that cross the line,
With crossorigin="anonymous" we sprinkle cheer,
External resources safe and clear!
From Gutenberg's change, this rabbit takes pride, ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding a plugin-owned crossorigin attribute injection implementation.
Linked Issues check ✅ Passed The PR fully implements the required functionality from issue #17: adds plugin-owned crossorigin injection, handles IMG and other tags with proper CORS attributes, includes fallback logic, and provides comprehensive test coverage.
Out of Scope Changes check ✅ Passed All changes are directly related to the linked issue #17 objectives: the new csme_add_crossorigin_attributes() function, updated output buffer callback, and test suite all focus on crossorigin attribute injection.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch copilot/ensure-images-use-cors-attribute

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@adamsilverstein

Copy link
Copy Markdown
Owner

@copilot this only needs to target the elements core removed, the remainder are still covered in core.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
tests/Test_Add_Crossorigin_Attributes.php (1)

85-132: Add regression tests for two missing edge cases.

Please add coverage for protocol-relative external URLs and for preserving an existing parent crossorigin when processing cross-origin <source>.

✅ Suggested tests
+	/**
+	 * Adds crossorigin to protocol-relative cross-origin URLs.
+	 */
+	public function test_adds_crossorigin_to_protocol_relative_external_url() {
+		$html   = '<script src="//cdn.example.com/app.js"></script>';
+		$result = csme_add_crossorigin_attributes( $html );
+
+		$this->assertStringContainsString( 'crossorigin="anonymous"', $result );
+	}
+
+	/**
+	 * Does not overwrite an existing parent crossorigin when source is cross-origin.
+	 */
+	public function test_does_not_overwrite_parent_crossorigin_for_source() {
+		$html   = '<video crossorigin="use-credentials"><source src="https://cdn.example.com/video.mp4"></video>';
+		$result = csme_add_crossorigin_attributes( $html );
+
+		$this->assertStringContainsString( 'crossorigin="use-credentials"', $result );
+		$this->assertStringNotContainsString( 'crossorigin="anonymous"', $result );
+	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/Test_Add_Crossorigin_Attributes.php` around lines 85 - 132, Add two
regression tests to tests/Test_Add_Crossorigin_Attributes.php that exercise
csme_add_crossorigin_attributes for (1) protocol-relative external URLs (e.g.,
an <img> or <source> with src="//cdn.example.com/...") and assert that the
parent element gains crossorigin="anonymous", and (2) preserving an existing
parent crossorigin when a cross-origin <source> is processed (e.g., a <video
crossorigin="use-credentials"><source src="https://..."></video>) and assert the
parent's crossorigin remains unchanged. Ensure the new test method names clearly
describe the cases (e.g., test_handles_protocol_relative_urls and
test_preserves_existing_parent_crossorigin) and use assertions consistent with
the file (assertStringContainsString/assertSame/assertStringNotContainsString)
to verify behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@includes/cross-origin-isolation.php`:
- Around line 169-174: The SOURCE branch currently finds the parent via
$processor->seek('audio-video-parent') and unconditionally calls
$processor->set_attribute('crossorigin','anonymous'), which can overwrite an
existing parent crossorigin; change this to first inspect the parent’s
crossorigin (e.g. via $processor->get_attribute('crossorigin') or has_attribute
if available on the found $sought) and only call
set_attribute('crossorigin','anonymous') when no crossorigin value is present
(null/empty) so existing values are preserved.
- Line 168: The conditional uses str_starts_with() which breaks PHP 7.4
compatibility; replace calls to str_starts_with($url, $site_url) and
str_starts_with($url, '/') with equivalent strpos checks (e.g., strpos($url,
$site_url) === 0 and strpos($url, '/') === 0) or alternatively raise the
project's minimum PHP version in composer.json/readme.txt to 8.0; update the
condition that references $url, $site_url, and $crossorigin in
includes/cross-origin-isolation.php to use the strpos-based checks to maintain
PHP 7.4 support.
- Line 168: The current condition treating root-relative URLs uses !
str_starts_with($url, '/') which incorrectly classifies protocol-relative URLs
('//cdn...') as root-relative; update the conditional in
includes/cross-origin-isolation.php so the "root-relative" check only matches a
single leading slash (i.e., use str_starts_with($url, '/') && !
str_starts_with($url, '//') when deciding a root-relative URL), so
protocol-relative URLs are considered cross-origin and will get
crossorigin="anonymous" added when appropriate.

---

Nitpick comments:
In `@tests/Test_Add_Crossorigin_Attributes.php`:
- Around line 85-132: Add two regression tests to
tests/Test_Add_Crossorigin_Attributes.php that exercise
csme_add_crossorigin_attributes for (1) protocol-relative external URLs (e.g.,
an <img> or <source> with src="//cdn.example.com/...") and assert that the
parent element gains crossorigin="anonymous", and (2) preserving an existing
parent crossorigin when a cross-origin <source> is processed (e.g., a <video
crossorigin="use-credentials"><source src="https://..."></video>) and assert the
parent's crossorigin remains unchanged. Ensure the new test method names clearly
describe the cases (e.g., test_handles_protocol_relative_urls and
test_preserves_existing_parent_crossorigin) and use assertions consistent with
the file (assertStringContainsString/assertSame/assertStringNotContainsString)
to verify behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8053f88d-1fb9-44d7-a214-6e13e6c8c01a

📥 Commits

Reviewing files that changed from the base of the PR and between 2c28192 and a59a92a.

📒 Files selected for processing (2)
  • includes/cross-origin-isolation.php
  • tests/Test_Add_Crossorigin_Attributes.php

Comment thread includes/cross-origin-isolation.php Outdated
Comment thread includes/cross-origin-isolation.php Outdated

Copilot AI commented Mar 19, 2026 •

Copy link
Copy Markdown
Contributor Author

@copilot this only needs to target the elements core removed, the remainder are still covered in core.

Updated in b1ae169. csme_add_crossorigin_to_images() now only targets IMG tags. The output buffer first delegates to wp_add_crossorigin_attributes() / gutenberg_add_crossorigin_attributes() for all other elements, then applies IMG-only injection.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/repos/PHPCSStandards/PHPCSExtra/zipball/b598aa890815b8df16363271b659d73280129101
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/PHPCSStandards/PHPCSUtils/zipball/c216317e96c8b3f5932808f9b0f1f7a14e3bbf55
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/0ca86845ce43291e8f5692c7356fccf3bcf02bf4
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/845eb62303d2ca9b289ef216356568ccc075ffd1
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/9fb324479acf6f39452e0655d2429cc0d3914243
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/244d7b04fc4bc2117c15f5abe23eb933b5f02bbf
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/7c8d18b4d90dac9e86b0869a608fa09158e168fa
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/7795ec6fa05663d716a549d0b44e47ffc8b0d4a6
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/1a6aecc9ebe4a9cea4e1047d0e6c496e52314c27
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/comparator/zipball/e4df00b9b3571187db2831ae9aada2c6efbd715d
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/exporter/zipball/14c6ba52f95a36c3d27c835d65efc7123c446e8c
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/global-state/zipball/b6781316bdcd28260904e7cc18ec983d0d2ef4f6
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/85402a822d1ecf1db1096959413d35e1c37cf1a5
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b36f02317466907a230d3aa1d34467041271ef4a
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/539c6691e0623af6dc6f9c20384c120f963465a0
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/wp-phpunit/wp-phpunit/zipball/15fd216bf6516670d8d07b938675925bfa5c15b0
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kTU1T9 /usr/bin/composer install --quiet (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title Add plugin-owned crossorigin="anonymous" attribute injection Add crossorigin="anonymous" to IMG elements after Gutenberg core change Mar 19, 2026
@adamsilverstein
adamsilverstein marked this pull request as ready for review March 19, 2026 03:53
@adamsilverstein

Copy link
Copy Markdown
Owner

@copilot address the feedback from code rabbit

Copilot AI commented Mar 19, 2026 •

Copy link
Copy Markdown
Contributor Author

@copilot address the feedback from code rabbit

Addressed in f06deee:

  • Replaced str_starts_with() with strpos() for PHP 7.4 compatibility
  • Fixed protocol-relative URLs (//cdn.example.com) being incorrectly treated as root-relative — they now correctly get crossorigin="anonymous"
  • Added early-continue guard so strpos() is only called on string URLs (PHP 8.1+ safety)
  • Added test for protocol-relative URL handling

The SOURCE → parent crossorigin overwrite issue from CodeRabbit is no longer applicable since the function was narrowed to IMG-only in the previous commit.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/repos/PHPCSStandards/PHPCSExtra/zipball/b598aa890815b8df16363271b659d73280129101
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/PHPCSStandards/PHPCSUtils/zipball/c216317e96c8b3f5932808f9b0f1f7a14e3bbf55
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/0ca86845ce43291e8f5692c7356fccf3bcf02bf4
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/845eb62303d2ca9b289ef216356568ccc075ffd1
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/9fb324479acf6f39452e0655d2429cc0d3914243
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/244d7b04fc4bc2117c15f5abe23eb933b5f02bbf
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/7c8d18b4d90dac9e86b0869a608fa09158e168fa
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/7795ec6fa05663d716a549d0b44e47ffc8b0d4a6
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/1a6aecc9ebe4a9cea4e1047d0e6c496e52314c27
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/comparator/zipball/e4df00b9b3571187db2831ae9aada2c6efbd715d
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/exporter/zipball/14c6ba52f95a36c3d27c835d65efc7123c446e8c
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/global-state/zipball/b6781316bdcd28260904e7cc18ec983d0d2ef4f6
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/85402a822d1ecf1db1096959413d35e1c37cf1a5
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b36f02317466907a230d3aa1d34467041271ef4a
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/539c6691e0623af6dc6f9c20384c120f963465a0
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)
  • https://api.github.com/repos/wp-phpunit/wp-phpunit/zipball/15fd216bf6516670d8d07b938675925bfa5c15b0
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/sbAOnb /usr/bin/composer install --quiet (http block)

If you need me to access, download, or install something from one of these locations, you can either:

@adamsilverstein

Copy link
Copy Markdown
Owner

Replaced str_starts_with() with strpos() for PHP 7.4 compatibility

@copilot pretty sure wordpress shims this funciton, so you can undo that change (verify)

Copilot AI commented Mar 19, 2026 •

Copy link
Copy Markdown
Contributor Author

Replaced str_starts_with() with strpos() for PHP 7.4 compatibility

@copilot pretty sure wordpress shims this funciton, so you can undo that change (verify)
...

Confirmed — WordPress provides a str_starts_with() polyfill since WP 5.9, and this plugin requires WP 6.8+. Reverted in 314bd68.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/repos/PHPCSStandards/PHPCSExtra/zipball/b598aa890815b8df16363271b659d73280129101
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/PHPCSStandards/PHPCSUtils/zipball/c216317e96c8b3f5932808f9b0f1f7a14e3bbf55
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/0ca86845ce43291e8f5692c7356fccf3bcf02bf4
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/b2TDnu /usr/bin/composer install --quiet (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/845eb62303d2ca9b289ef216356568ccc075ffd1
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/b2TDnu /usr/bin/composer install --quiet (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/9fb324479acf6f39452e0655d2429cc0d3914243
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/b2TDnu /usr/bin/composer install --quiet (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/244d7b04fc4bc2117c15f5abe23eb933b5f02bbf
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/b2TDnu /usr/bin/composer install --quiet (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/7c8d18b4d90dac9e86b0869a608fa09158e168fa
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/7795ec6fa05663d716a549d0b44e47ffc8b0d4a6
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/1a6aecc9ebe4a9cea4e1047d0e6c496e52314c27
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/b2TDnu /usr/bin/composer install --quiet (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/b2TDnu /usr/bin/composer install --quiet (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/b2TDnu /usr/bin/composer install --quiet (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/b2TDnu /usr/bin/composer install --quiet (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/b2TDnu /usr/bin/composer install --quiet (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/b2TDnu /usr/bin/composer install --quiet (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/b2TDnu /usr/bin/composer install --quiet (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/sebastianbergmann/comparator/zipball/e4df00b9b3571187db2831ae9aada2c6efbd715d
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/b2TDnu /usr/bin/composer install --quiet (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/b2TDnu /usr/bin/composer install --quiet (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/b2TDnu /usr/bin/composer install --quiet (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/b2TDnu /usr/bin/composer install --quiet (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/sebastianbergmann/exporter/zipball/14c6ba52f95a36c3d27c835d65efc7123c446e8c
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/b2TDnu /usr/bin/composer install --quiet (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/sebastianbergmann/global-state/zipball/b6781316bdcd28260904e7cc18ec983d0d2ef4f6
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/b2TDnu /usr/bin/composer install --quiet (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/b2TDnu /usr/bin/composer install --quiet (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/85402a822d1ecf1db1096959413d35e1c37cf1a5
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/b2TDnu /usr/bin/composer install --quiet (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/b2TDnu /usr/bin/composer install --quiet (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/b2TDnu /usr/bin/composer install --quiet (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/b2TDnu /usr/bin/composer install --quiet (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/b2TDnu /usr/bin/composer install --quiet (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b36f02317466907a230d3aa1d34467041271ef4a
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/539c6691e0623af6dc6f9c20384c120f963465a0
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/b2TDnu /usr/bin/composer install --quiet (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)
  • https://api.github.com/repos/wp-phpunit/wp-phpunit/zipball/15fd216bf6516670d8d07b938675925bfa5c15b0
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/j3iGmA /usr/bin/composer install --no-progress ps (http block)

If you need me to access, download, or install something from one of these locations, you can either:

@adamsilverstein

Copy link
Copy Markdown
Owner

Triaged against WordPress 7.1 trunk: the approach here is still needed (core's wp_add_crossorigin_attributes() excludes IMG). Keeping open; please rebase after #23/#24 land per the plan in #25.

@adamsilverstein adamsilverstein left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed against WordPress 7.1 trunk. The premise holds: core's wp_add_crossorigin_attributes() handles AUDIO/LINK/SCRIPT/VIDEO/SOURCE and not IMG, and the delegate-then-augment structure is right. The WP_HTML_Tag_Processor implementation and test coverage look good, including correctly treating protocol-relative URLs as cross-origin (which core gets wrong). A few changes needed:

  1. Gate IMG handling on require-corp (Safari) only. crossorigin="anonymous" switches the image fetch to CORS mode. Under Cross-Origin-Embedder-Policy: credentialless (Firefox), plain no-cors images already load fine without the attribute - but with it, any image whose server does not send Access-Control-Allow-Origin will fail to load entirely. That makes this a regression for Firefox users while only Safari (require-corp) benefits, since there a cross-origin image without CORP/CORS is blocked anyway and CORS mode is its only chance to load. The output buffer callback already knows $is_safari / which COEP value it sent; only call csme_add_crossorigin_to_images() in the require-corp case. (This is likely the same reason Gutenberg removed IMG handling in WordPress/gutenberg#76618 when moving to credentialless isolation.)

  2. Handle srcset. An IMG whose src is same-origin but whose srcset includes cross-origin candidates (or which has only srcset) is missed. Checking both attributes and adding the attribute when any candidate URL is cross-origin would match how core checks multiple attributes per tag (e.g. VIDEO src + poster).

  3. Rebase onto the current stack. #27 (7.1 function-name/init fixes) and #28 (HEIC module removal) touch includes/cross-origin-isolation.php and its neighbors; this branch is based on an older main. Please rebase once those merge - the @since 0.3.0 tag can stay, matching the next release.

Happy to re-review after the update.

Copilot AI requested a review from adamsilverstein July 16, 2026 16:16
@adamsilverstein
adamsilverstein force-pushed the copilot/ensure-images-use-cors-attribute branch 2 times, most recently from d33c65a to 1a53613 Compare July 16, 2026 16:24
@adamsilverstein

Copy link
Copy Markdown
Owner

Applied the requested changes directly on this branch:

  • Rebased onto current main (the build-zip changes from Add composer build command to package plugin zip #22).
  • Gated IMG rewriting to require-corp: csme_add_crossorigin_to_images() now only runs when the COEP value sent is require-corp (Safari). Under credentialless (Firefox) images are left alone, since forcing CORS mode there would break images from servers without Access-Control-Allow-Origin.
  • srcset support: an image is now treated as cross-origin if its src or any srcset candidate is cross-origin; the origin check moved into a csme_is_cross_origin_url() helper. Also aligned the existing-attribute check with core (null !== instead of is_string, so a bare boolean crossorigin attribute is respected).
  • Tests: three new srcset cases in Test_Add_Crossorigin_Attributes, plus two buffer-level tests in Test_Output_Buffer asserting images are rewritten under require-corp and untouched under credentialless.

PHPCS clean; PHPUnit 66 tests passing locally (the 3 pre-existing header-assertion failures are the no-xdebug CLI environment issue, they pass in CI). Since I authored these changes, this PR needs a fresh pair of eyes rather than my re-review.

Core's wp_add_crossorigin_attributes() excludes IMG (removed in
Gutenberg#76618), but under require-corp isolation on Safari,
cross-origin images without CORP headers are blocked and a CORS
request is their only chance to load. Delegate all other elements
to core/Gutenberg, then add the attribute to IMG tags whose src or
srcset references another origin.

Only applies under require-corp: under credentialless (Firefox)
images load fine without it, and forcing CORS mode would break
images from servers that do not send Access-Control-Allow-Origin.

Rebuilt on main past the 7.1 integration and v1.0.0 changes, which
conflicted with every commit of the original branch history.
@adamsilverstein
adamsilverstein force-pushed the copilot/ensure-images-use-cors-attribute branch from 1a53613 to d15471a Compare July 16, 2026 17:24
@adamsilverstein

Copy link
Copy Markdown
Owner

Rebuilt the branch on current main. Every commit in the old history conflicted with the WordPress 7.1 integration (#27) and v1.0.0 (#32) changes to includes/cross-origin-isolation.php, so rather than resolving six sequential conflicts of superseded intermediate states, I reset onto main and re-applied the final state as a single commit (d15471a). The net diff is unchanged from what was approved, adapted to main:

  • csme_add_crossorigin_to_images() and csme_is_cross_origin_url() as before: IMG-only, require-corp gated, src + srcset, protocol-relative treated as cross-origin, existing crossorigin attributes preserved.
  • The output buffer delegates AUDIO/LINK/SCRIPT/VIDEO/SOURCE to wp_add_crossorigin_attributes() / the Gutenberg equivalent, then augments IMG only on Safari.
  • All 13 Test_Add_Crossorigin_Attributes tests and the 2 output-buffer image tests carried over verbatim.
  • @since tags updated from 0.3.0 to 1.1.0 and an Unreleased changelog entry added, since this now lands after the 1.0.0 release.

Verified locally: PHPCS clean; PHPUnit 37/40 with only the 3 known local-only Test_Output_Buffer header failures (empty headers_list() in CLI without xdebug - they pass in CI).

The earlier CodeRabbit findings are resolved: the str_starts_with() concern is covered by the WP 5.9+ polyfill, and the SOURCE-overwrites-parent issue was in code removed by the IMG-only rewrite.

The JS-side counterpart (MutationObserver adds crossorigin to images under credentialless too) is tracked separately in #31.

@adamsilverstein
adamsilverstein merged commit b87a485 into main Jul 16, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ensure images use crossorigin="anonymous" after Gutenberg core change

2 participants