Skip to content
Merged
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
15 changes: 13 additions & 2 deletions includes/functions-html.php
Original file line number Diff line number Diff line change
Expand Up @@ -524,8 +524,19 @@ function yourls_die( string $message = '', string $title = '', int $header_code
yourls_html_head();
yourls_html_logo();
}
echo yourls_esc_html( yourls_apply_filter( 'die_title', "<h2>$title</h2>" ) );
echo yourls_esc_html( yourls_apply_filter( 'die_message', "<p>$message</p>" ) );

$title = yourls_apply_filter( 'die_title', "<h2>$title</h2>" );
$message = yourls_apply_filter( 'die_message', "<p>$message</p>" );
$allowed = [
'strong' => [],
'em' => [],
'tt' => [],
'code' => [],
'h2' => [],
'br' => [],
'p' => ['class' => true],
];
echo yourls_esc_html_with_whitelist( $title . $message, $allowed );
// Hook into 'yourls_die' to add more elements or messages to that page
yourls_do_action( 'yourls_die' );
if( !yourls_did_action( 'html_footer' ) ) {
Expand Down
7 changes: 7 additions & 0 deletions includes/functions-kses.php
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,13 @@ function yourls_kses_named_entities($matches) {
if ( empty($matches[1]) )
return '';

// KSES globals are normally populated on the 'plugins_loaded' action. This can run
// earlier though (eg yourls_die() on a DB connection error, before plugins load), so
// make sure the allowed entity names are available.
if ( ! is_array($yourls_allowedentitynames) ) {
yourls_kses_init();
}

$i = $matches[1];
return ( ( ! in_array($i, $yourls_allowedentitynames) ) ? "&amp;$i;" : "&$i;" );
}
Expand Down
10 changes: 8 additions & 2 deletions includes/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -1234,13 +1234,19 @@ function yourls_check_maintenance_mode() {
* @since 1.6
* @see yourls_get_protocol()
*
* @param string $url URL to be check
* @param string $url URL to be checked
* @param array $protocols Optional. Array of protocols, defaults to global $yourls_allowedprotocols
* @return bool true if protocol allowed, false otherwise
*/
function yourls_is_allowed_protocol( $url, $protocols = [] ) {
function yourls_is_allowed_protocol(string $url, array $protocols = [] ): bool {
if ( empty( $protocols ) ) {
global $yourls_allowedprotocols;
// KSES globals are normally populated on the 'plugins_loaded' action. This can run
// earlier though (eg yourls_die() on a DB connection error, before plugins load), so
// make sure the allowed protocols are available.
if ( ! is_array( $yourls_allowedprotocols ) ) {
yourls_kses_init();
}
$protocols = $yourls_allowedprotocols;
}

Expand Down
Binary file modified includes/geo/GeoLite2-Country.mmdb
Binary file not shown.
32 changes: 32 additions & 0 deletions tests/tests/format/KSESTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,36 @@ function test_sanitize_title() {
$this->assertTrue( is_array( yourls_kses_allowed_tags_all() ) );
}

/**
* KSES globals are populated on 'plugins_loaded'. Make sure entity normalization
* (yourls_esc_html) does not blow up if it runs earlier, eg yourls_die() on a DB
* connection error before plugins are loaded
*/
function test_esc_html_works_before_kses_init() {
global $yourls_allowedentitynames;
// Simulate the not-yet-initialized state
$yourls_allowedentitynames = null;

$escaped = yourls_esc_html( "Unknown database &eacute; <b>x</b> 'q'" );

// No TypeError, output is escaped, and the global got lazily populated
$this->assertIsString( $escaped );
$this->assertStringContainsString( '&lt;b&gt;', $escaped );
$this->assertIsArray( $yourls_allowedentitynames );
}

/**
* Same early-call safety for protocol checking, which reads $yourls_allowedprotocols.
*/
function test_is_allowed_protocol_works_before_kses_init() {
global $yourls_allowedprotocols;
// Simulate the not-yet-initialized state
$yourls_allowedprotocols = null;

// No TypeError on in_array() against a null protocols list
$this->assertTrue( yourls_is_allowed_protocol( 'http://example.com' ) );
$this->assertFalse( yourls_is_allowed_protocol( 'javascript:alert(1)' ) );
$this->assertIsArray( $yourls_allowedprotocols );
}

}