Skip to content

Fix: hide debug HTML comments in REST and Ajax responses#1021

Merged
donnchawp merged 4 commits into
trunkfrom
cherry-pick/436-hide-debug-rest-ajax
May 27, 2026
Merged

Fix: hide debug HTML comments in REST and Ajax responses#1021
donnchawp merged 4 commits into
trunkfrom
cherry-pick/436-hide-debug-rest-ajax

Conversation

@kraftbj
Copy link
Copy Markdown
Contributor

@kraftbj kraftbj commented Apr 7, 2026

Summary

  • Prevents WP Super Cache from appending HTML debug comments (<!-- ... -->) to non-HTML responses such as REST API, Ajax, JSON API, and WooCommerce API requests.
  • Adds checks for REST_REQUEST, JSON_REQUEST, WC_API_REQUEST constants and wp_doing_ajax() to both wp_cache_append_tag() and wp_cache_add_to_buffer(), bailing early when the response is not standard HTML.

Originally proposed by @jom in #436.

This is a manual cherry-pick of the changes from closed PR #436, adapted to the current codebase. See #436.

Test plan

  • Verify REST API responses (e.g., /wp-json/wp/v2/posts) do not contain <!-- ... --> debug comments when Super Cache debug mode is enabled.
  • Verify Ajax responses (admin-ajax.php) do not contain HTML debug comments.
  • Verify WooCommerce API responses do not contain HTML debug comments.
  • Verify normal HTML page responses still include debug comments when debug mode is enabled.
  • Verify that non-HTML responses (no <html tag) continue to be excluded as before.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR prevents WP Super Cache debug HTML comments (<!-- ... -->) from being appended to non-HTML responses (notably REST/JSON, WooCommerce API, and Ajax), avoiding response corruption for API consumers while preserving existing debug logging behavior.

Changes:

  • Add early-bail conditions in wp_cache_append_tag() to skip appending debug HTML comments for REST/JSON/WC API and Ajax requests.
  • Apply the same early-bail logic in wp_cache_add_to_buffer() so other debug HTML comment insertions are also suppressed for non-HTML response contexts.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread wp-cache-phase2.php Outdated
Comment thread wp-cache-phase2.php Outdated
@kraftbj kraftbj force-pushed the cherry-pick/436-hide-debug-rest-ajax branch from 4d15180 to 18753eb Compare April 7, 2026 22:02
kraftbj and others added 2 commits April 7, 2026 17:24
…e check

The REST/Ajax/JSON/WC bail condition was copy-pasted into both wp_cache_append_tag() and wp_cache_add_to_buffer(). Move it into a single named predicate so the two call sites can't drift, and drop the explanatory comment the inline condition needed.
@donnchawp donnchawp marked this pull request as ready for review May 27, 2026 16:25
@donnchawp
Copy link
Copy Markdown
Contributor

This comment was generated by AI.

Pushed a small refactor on top of your cherry-pick (2ac3825) and marked the PR ready for review.

The REST/Ajax/JSON/WC bail condition was copy-pasted identically into both wp_cache_append_tag() and wp_cache_add_to_buffer(). I moved it into a single predicate so the two sites can't drift:

function wpsc_skip_debug_output( $buffer ) {
	return strpos( $buffer, '<html' ) === false ||
		( defined( 'REST_REQUEST' ) && REST_REQUEST ) ||
		( defined( 'JSON_REQUEST' ) && JSON_REQUEST ) ||
		( defined( 'WC_API_REQUEST' ) && WC_API_REQUEST ) ||
		( function_exists( 'wp_doing_ajax' ) && wp_doing_ajax() );
}

Both call sites are now if ( wpsc_skip_debug_output( $buffer ) ) { ... }, each keeping its own wp_cache_debug() line and return false. No behavioural change — same constants and guards as before; the named function also let the explanatory comment go. Net −6 lines.

One open item: this path has no automated coverage (see #1051), so the suppression is currently verified by the manual test plan only.

advanced-cache.php already treats XMLRPC_REQUEST as a non-HTML response type; keep wpsc_skip_debug_output() consistent so XML-RPC bodies stay clean regardless of the <html sniff.
@donnchawp
Copy link
Copy Markdown
Contributor

This comment was generated by AI.

Note on the XMLRPC_REQUEST clause I added to wpsc_skip_debug_output() (737ffb9): it's defensive/documentation, not load-bearing.

In practice XML-RPC requests never reach this code path — xmlrpc.php is already classified as backend in wpsc_is_backend() (wp-cache-phase2.php:803) and is in the $auto_rejected list (wp-cache-phase2.php:1877), so the output buffer is never built for it. XMLRPC_REQUEST is only defined inside xmlrpc.php, so the clause can't fire unless some other page both defines that constant and pushes XML through the cache buffer — a case that doesn't occur today.

It's kept for intent/parity with advanced-cache.php (which also enumerates XMLRPC_REQUEST), not because it's reachable.

The other clauses are reachable and necessary: REST (/wp-json/) rewrites to index.php so it isn't rejected upstream, and a JSON/REST body can contain the literal substring <html, which would defeat the old strpos sniff on its own — that's the actual bug this PR fixes.

@donnchawp donnchawp merged commit 1c6e7e2 into trunk May 27, 2026
6 of 7 checks passed
@donnchawp donnchawp mentioned this pull request May 27, 2026
@donnchawp donnchawp deleted the cherry-pick/436-hide-debug-rest-ajax branch May 27, 2026 18:01
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.

4 participants