Skip to content

Commit 2068d4e

Browse files
committed
Canonical: prevent "Undefined array key" PHP warnings when host is not set.
This change is necessary to prevent scanning tools from polluting debug/error logs of some hosting configurations with PHP warnings simply by omitting the Host header from their requests. This commit makes sure that all of the required `host`, `path`, `query`, and `scheme` array keys inside of the `redirect_canonical()` function are always set after various operations have been performed on them. It also includes 1 new test case and 2 additional tests, to verify the problem and its fix are working as intended, as well as a small modification to the `get_canonical()` phpunit helper specifically to account for `HTTP_HOST` maybe not being set. Props artz91, johnjamesjacoby, mindctrl, sirlouen. Fixes #63316. git-svn-id: https://develop.svn.wordpress.org/trunk@61136 602fd350-edb4-49c9-b593-d223f7449a82
1 parent ef32a8c commit 2068d4e

File tree

3 files changed

+58
-15
lines changed

3 files changed

+58
-15
lines changed

src/wp-includes/canonical.php

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -77,18 +77,18 @@ function redirect_canonical( $requested_url = null, $do_redirect = true ) {
7777
return;
7878
}
7979

80+
// Notice fixing.
81+
$original += array(
82+
'host' => '',
83+
'path' => '',
84+
'query' => '',
85+
'scheme' => '',
86+
);
87+
8088
$redirect = $original;
8189
$redirect_url = false;
8290
$redirect_obj = false;
8391

84-
// Notice fixing.
85-
if ( ! isset( $redirect['path'] ) ) {
86-
$redirect['path'] = '';
87-
}
88-
if ( ! isset( $redirect['query'] ) ) {
89-
$redirect['query'] = '';
90-
}
91-
9292
/*
9393
* If the original URL ended with non-breaking spaces, they were almost
9494
* certainly inserted by accident. Let's remove them, so the reader doesn't
@@ -616,12 +616,12 @@ function redirect_canonical( $requested_url = null, $do_redirect = true ) {
616616
}
617617

618618
// Notice prevention after new parse_url( $redirect_url ) calls
619-
if ( ! isset( $redirect['path'] ) ) {
620-
$redirect['path'] = '';
621-
}
622-
if ( ! isset( $redirect['query'] ) ) {
623-
$redirect['query'] = '';
624-
}
619+
$redirect += array(
620+
'host' => '',
621+
'path' => '',
622+
'query' => '',
623+
'scheme' => '',
624+
);
625625

626626
// Trailing /index.php.
627627
$redirect['path'] = preg_replace( '|/' . preg_quote( $wp_rewrite->index, '|' ) . '/*?$|', '/', $redirect['path'] );

tests/phpunit/includes/testcase-canonical.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,11 @@ public function assertCanonical( $test_url, $expected, $ticket = 0, $expected_do
345345
* the fully-qualified URL as generated by redirect_canonical().
346346
*/
347347
public function get_canonical( $test_url ) {
348-
$test_url = home_url( $test_url );
348+
if ( isset( $_SERVER['HTTP_HOST'] ) ) {
349+
$test_url = home_url( $test_url );
350+
} else {
351+
$test_url = '';
352+
}
349353

350354
$can_url = redirect_canonical( $test_url, false );
351355
if ( ! $can_url ) {

tests/phpunit/tests/canonical/noRewrite.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,45 @@ public function data() {
274274
array( '/?feed=rss&p=1', '/?feed=rss2&p=1', 24623 ),
275275

276276
array( '/?comp=East+(North)', '/?comp=East+(North)', 49347 ),
277+
278+
array( null, '/', 63316 ), // No Path and Query
279+
);
280+
}
281+
282+
/**
283+
* Test the canonical URL when the host header is not set.
284+
*
285+
* @ticket 63316
286+
* @dataProvider data_missing_host_header
287+
* @param string $wp_home The WP_HOME value to set.
288+
* @param string $expected_url The expected canonical URL.
289+
*/
290+
public function test_missing_host_header( $wp_home, $expected_url ) {
291+
$_SERVER['HTTP_HOST'] = null;
292+
add_filter(
293+
'pre_option_home',
294+
static function () use ( $wp_home ) {
295+
return $wp_home;
296+
}
297+
);
298+
$this->assertCanonical( '/', $expected_url, 63316 );
299+
}
300+
301+
/**
302+
* Data provider for test_missing_host_header().
303+
*
304+
* @return array[]
305+
*/
306+
public function data_missing_host_header() {
307+
return array(
308+
'no port' => array(
309+
'wp_home' => 'http://example.com',
310+
'expected_url' => ':///',
311+
),
312+
'with port' => array(
313+
'wp_home' => 'http://example.com:8889',
314+
'expected_url' => '://:8889/',
315+
),
277316
);
278317
}
279318
}

0 commit comments

Comments
 (0)