[wp-trac] [WordPress Trac] #59282: WordPress should register custom error and exception handlers
WordPress Trac
noreply at wordpress.org
Tue Jul 1 17:50:50 UTC 2025
#59282: WordPress should register custom error and exception handlers
-------------------------------------------------+-------------------------
Reporter: bjorsch | Owner: (none)
Type: feature request | Status: new
Priority: normal | Milestone: Future
| Release
Component: Bootstrap/Load | Version: 6.4
Severity: normal | Resolution:
Keywords: has-patch dev-feedback needs-test- | Focuses:
info |
-------------------------------------------------+-------------------------
Comment (by bjorsch):
I'm still not very clear on what you're actually asking for, but let's
give it a try.
The Use-Case is as described in the ticket: We want PHP error messages
(including from uncaught exceptions) and warnings displayed in the browser
to be properly encoded to avoid HTML injection, but escaping at the time
the message is generated is not a good solution because (1) we can only do
that for code we control and (2) we don't know whether the message is
going to be displayed in a browser, or from wp-cli, or written to a log
file, or what else. The generally recommended practice (outside of
WordPress) is to escape at the time the value is being output, which is
what the PR here implements.
As for code to be used for testing, here's a simple mu-plugin to generate
various types of errors.
{{{#!php
<?php
// Set appropriate ini settings. You'll at least want to test with
html_errors both on and off.
// You could also do this in php.ini or the like instead of here.
ini_set( 'display_errors', true );
ini_set( 'html_errors', false );
function xxx_generate_error() {
// Set this to 'warning', 'error', 'exception', or 'internal' to
test different kinds of error messaging.
$test = 'internal';
// Test error message that contains some HTML that should not be
rendered.
$msg = 'This is a test: <script>alert("oops");</script>';
switch ( $test ) {
case 'warning':
// A warning. The value from `error_get_last()`
should reflect the message above.
trigger_error( $msg, E_USER_WARNING );
error_log( var_export( error_get_last(), true ) );
break;
case 'error':
// An error.
trigger_error( $msg, E_USER_ERROR );
break;
case 'exception':
// An uncaught exception.
throw new RuntimeException( $msg );
break;
case 'internal':
// A warning generated by PHP itself, where we
can't reasonably HTML-encode the input.
$arr = array();
$var = $arr[ $msg ];
break;
}
}
// You may want to try different actions to test handling during later
parts of the request, or even just call it directly to test handling
during the mu-plugin load.
add_action( 'plugins_loaded', 'xxx_generate_error' );
}}}
The comments indicate parts of the mu-plugin that you may want to edit to
test different scenarios. In real life, errors and warnings would be
generated by error cases or unintentional bugs in core, plugins, and
themes.
As for triggering the mu-plugin, you'd want to do so in various ways:
1. Visit a page in a browser.
2. Run a wp-cli command.
3. Either of the above, but then look at what is written to `debug.log`.
Acceptance criteria for each case are:
1. The message is shown as text, **not** rendered as HTML.
2. On the console, the wp-cli output of the message does not have HTML-
style encoding.
3. The log file does not contain HTML-style encoding either.
WordPress's current behavior with this mu-plugin will incorrectly render
the message as HTML for 'warning', 'error', and 'internal', and for
'exception' too when html_errors is off.
There may be additional triggering methods to test. For example, if we
have API endpoints that catch and report errors as properly formatted
responses rather than letting PHP spit out HTML or something malformed,
those should produce output that does escaping appropriate to the output
format rather than HTML-style encoding. For example, a JSON response might
represent it as `"This is a test:
\u003Cscript\u003Ealert(\"oops\");\u003C/script\u003E"` (with the client
expected to escape it properly for however it's planning to output the
response), not `"This is a test:
<script>alert("oops");<\/script>"` where the client
would have to HTML-decode it before using it in a non-HTML context.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/59282#comment:18>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list