Skip to content
Open
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
8 changes: 7 additions & 1 deletion src/wp-includes/class-wp-roles.php
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,13 @@ public function init_roles() {
$this->role_objects = array();
$this->role_names = array();
foreach ( array_keys( $this->roles ) as $role ) {
$this->role_objects[ $role ] = new WP_Role( $role, $this->roles[ $role ]['capabilities'] );
$role_capabilities = $this->roles[ $role ]['capabilities'] ?? array();

if ( ! is_array( $role_capabilities ) ) {
$role_capabilities = array();
}

$this->role_objects[ $role ] = new WP_Role( $role, $role_capabilities );
$this->role_names[ $role ] = $this->roles[ $role ]['name'];
}

Expand Down
5 changes: 4 additions & 1 deletion src/wp-includes/class-wp-user-query.php
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,10 @@ public function prepare_query( $query = array() ) {
$caps_with_roles = array();

foreach ( $available_roles as $role => $role_data ) {
$role_caps = array_keys( array_filter( $role_data['capabilities'] ) );
$role_capabilities = $role_data['capabilities'] ?? array();
$role_caps = is_array( $role_capabilities )
? array_keys( array_filter( $role_capabilities ) )
: array();

foreach ( $capabilities as $cap ) {
if ( in_array( $cap, $role_caps, true ) ) {
Expand Down
47 changes: 47 additions & 0 deletions tests/phpunit/tests/user/query.php
Original file line number Diff line number Diff line change
Expand Up @@ -1959,6 +1959,53 @@ public function test_capability__in_capability__not_in_combined() {
}
}

/**
* A role stored without a 'capabilities' key (for example, left behind by a
* deactivated plugin) should be skipped rather than causing a fatal error.
*
* @ticket 62600
*/
public function test_capability_query_with_role_missing_capabilities_key() {
global $wp_roles;

$wp_roles->add_role( 'role_missing_caps', 'Role Missing Caps' );

$roles = get_option( $wp_roles->role_key );
unset( $roles['role_missing_caps']['capabilities'] );
update_option( $wp_roles->role_key, $roles );

$wp_user_search = new WP_User_Query( array( 'capability' => 'read' ) );
$users = $wp_user_search->get_results();

$this->assertNotEmpty( $users );

$wp_roles->remove_role( 'role_missing_caps' );
}

/**
* A role whose 'capabilities' value isn't an array should be skipped rather
* than causing a fatal error, the same as a missing key.
*
* @ticket 62600
*/
public function test_capability_query_with_role_capabilities_not_an_array() {
global $wp_roles;

$wp_roles->add_role( 'role_invalid_caps', 'Role Invalid Caps' );

$roles = get_option( $wp_roles->role_key );

$roles['role_invalid_caps']['capabilities'] = false;
update_option( $wp_roles->role_key, $roles );

$wp_user_search = new WP_User_Query( array( 'capability' => 'read' ) );
$users = $wp_user_search->get_results();

$this->assertNotEmpty( $users );

$wp_roles->remove_role( 'role_invalid_caps' );
}

/**
* @ticket 16841
* @group ms-required
Expand Down
Loading