Skip to content

Commit

Permalink
PHP 8.1 | wp_xmlrpc_server::_insert_post(): fix passing null to non-n…
Browse files Browse the repository at this point in the history
…ullable and more

The `wp_xmlrpc_server::_insert_post()` method creates a new post via `wp_insert_post()` or updates an existing one via `wp_update_post()` (which subsequently calls `wp_insert_post()`), but the default/fall-back values used in the function were not in line with the default/fall-back values used in the `wp_insert_post()` function.

The `wp_insert_post()` function does a `wp_parse_args()` (array merge) of the received arguments with the defaults.
If any of the received arguments would be `null`, this would overwrite the default value (see: https://3v4l.org/bfVlv ) and will lead to "passing null to non-nullable" deprecation notices on PHP 8.1 for certain arguments.

Unfortunately, the conditional logic within the `wp_xmlrpc_server::_insert_post()` function itself often uses an `isset()` to trigger certain code blocks., so syncing the defaults with those used in the `wp_insert_post()` function was not an option.

So for this commit, I've:
* I've updated the default/fall-back values in the `$defaults` array only for those values where this would not lead to a change in the behaviour of the function.
* I've also added a safeguard function, filtering out all remaining `null` values from the `$post_data` array before it is passed on to the `wp_insert_post()` or `wp_update_post()` functions.
    Removing those values is safe as this means that these array keys will now:
    - either be set to the default/fall-back value as defined in `wp_insert_post()`.
    - or not be set and for those values which don't have a default/fall-back value in `wp_insert_post()`, `wp_insert_post()` does an `! empty()` or `isset()` check anyway and those array keys not being defined means that the result of those checks will remain the same.

Includes removing a couple of conditions which are now redundant.

Includes removing an `expectDeprecation()` in the `Tests_Date_XMLRPC` test class, which is now no longer needed.

Fixes various errors along the lines of:
```
36) Tests_XMLRPC_wp_newPost::test_no_content
json_decode(): Passing null to parameter #1 ($json) of type string is deprecated

/var/www/src/wp-includes/kses.php:2074
/var/www/src/wp-includes/class-wp-hook.php:307
/var/www/src/wp-includes/plugin.php:205
/var/www/src/wp-includes/post.php:2835
/var/www/src/wp-includes/post.php:2720
/var/www/src/wp-includes/post.php:4066
/var/www/src/wp-includes/class-wp-xmlrpc-server.php:1683
/var/www/src/wp-includes/class-wp-xmlrpc-server.php:1347
/var/www/tests/phpunit/tests/xmlrpc/wp/newPost.php:25
/var/www/vendor/bin/phpunit:123
```
  • Loading branch information
jrfnl committed Sep 20, 2022
1 parent 44e5bd1 commit 0f2b27b
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 22 deletions.
32 changes: 20 additions & 12 deletions src/wp-includes/class-wp-xmlrpc-server.php
Original file line number Diff line number Diff line change
Expand Up @@ -1412,19 +1412,19 @@ protected function _insert_post( $user, $content_struct ) {
$defaults = array(
'post_status' => 'draft',
'post_type' => 'post',
'post_author' => null,
'post_password' => null,
'post_excerpt' => null,
'post_content' => null,
'post_title' => null,
'post_date' => null,
'post_date_gmt' => null,
'post_author' => 0,
'post_password' => '',
'post_excerpt' => '',
'post_content' => '',
'post_title' => '',
'post_date' => '',
'post_date_gmt' => '',
'post_format' => null,
'post_name' => null,
'post_thumbnail' => null,
'post_parent' => null,
'ping_status' => null,
'comment_status' => null,
'post_parent' => 0,
'ping_status' => '',
'comment_status' => '',
'custom_fields' => null,
'terms_names' => null,
'terms' => null,
Expand Down Expand Up @@ -1499,11 +1499,11 @@ protected function _insert_post( $user, $content_struct ) {
$post_data['post_author'] = $user->ID;
}

if ( isset( $post_data['comment_status'] ) && 'open' !== $post_data['comment_status'] && 'closed' !== $post_data['comment_status'] ) {
if ( 'open' !== $post_data['comment_status'] && 'closed' !== $post_data['comment_status'] ) {
unset( $post_data['comment_status'] );
}

if ( isset( $post_data['ping_status'] ) && 'open' !== $post_data['ping_status'] && 'closed' !== $post_data['ping_status'] ) {
if ( 'open' !== $post_data['ping_status'] && 'closed' !== $post_data['ping_status'] ) {
unset( $post_data['ping_status'] );
}

Expand Down Expand Up @@ -1681,6 +1681,14 @@ protected function _insert_post( $user, $content_struct ) {
*/
$post_data = apply_filters( 'xmlrpc_wp_insert_post_data', $post_data, $content_struct );

// Remove all null values to allow for using the insert/update post default values for those keys instead.
$post_data = array_filter(
$post_data,
static function ( $value ) {
return null !== $value;
}
);

$post_ID = $update ? wp_update_post( $post_data, true ) : wp_insert_post( $post_data, true );
if ( is_wp_error( $post_ID ) ) {
return new IXR_Error( 500, $post_ID->get_error_message() );
Expand Down
10 changes: 0 additions & 10 deletions tests/phpunit/tests/date/xmlrpc.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,6 @@ public function tear_down() {
* @covers wp_xmlrpc_server::mw_newPost
*/
public function test_date_new_post() {
if ( PHP_VERSION_ID >= 80100 ) {
/*
* For the time being, ignoring PHP 8.1 "null to non-nullable" deprecations coming in
* via hooked in filter functions until a more structural solution to the
* "missing input validation" conundrum has been architected and implemented.
*/
$this->expectDeprecation();
$this->expectDeprecationMessageMatches( '`Passing null to parameter \#[0-9]+ \(\$[^\)]+\) of type [^ ]+ is deprecated`' );
}

$timezone = 'Europe/Helsinki';
update_option( 'timezone_string', $timezone );

Expand Down

0 comments on commit 0f2b27b

Please sign in to comment.