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
9 changes: 9 additions & 0 deletions phpcs.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -367,4 +367,13 @@
<exclude-pattern>/tests/*</exclude-pattern>
</rule>

<!-- Enforce PHP 8.0 named parameter compatibility.
Escalated from warning to error to prevent reserved keyword parameter names
(string, list, array, etc.) which break PHP 8.0+ named argument syntax.
See: Trac #59649
-->
<rule ref="Universal.NamingConventions.NoReservedKeywordParameterNames">
<type>error</type>
</rule>

</ruleset>
4 changes: 2 additions & 2 deletions src/wp-admin/includes/ajax-actions.php
Original file line number Diff line number Diff line change
Expand Up @@ -2432,7 +2432,7 @@ function wp_ajax_save_widget() {
}

ob_start();
call_user_func_array( $control['callback'], $control['params'] );
call_user_func_array( $control['callback'], wp_normalize_call_user_func_args( $control['params'] ) );
ob_end_clean();
break;
}
Expand All @@ -2451,7 +2451,7 @@ function wp_ajax_save_widget() {

$form = $wp_registered_widget_controls[ $widget_id ];
if ( $form ) {
call_user_func_array( $form['callback'], $form['params'] );
call_user_func_array( $form['callback'], wp_normalize_call_user_func_args( $form['params'] ) );
}

wp_die();
Expand Down
2 changes: 1 addition & 1 deletion src/wp-admin/includes/class-wp-screen.php
Original file line number Diff line number Diff line change
Expand Up @@ -913,7 +913,7 @@ public function render_screen_meta() {

// If it exists, fire tab callback.
if ( ! empty( $tab['callback'] ) ) {
call_user_func_array( $tab['callback'], array( $this, $tab ) );
call_user_func_array( $tab['callback'], wp_normalize_call_user_func_args( array( $this, $tab ) ) );
}
?>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/wp-admin/includes/dashboard.php
Original file line number Diff line number Diff line change
Expand Up @@ -1212,7 +1212,7 @@ function wp_dashboard_cached_rss_widget( $widget_id, $callback, $check_urls = ar
if ( $callback && is_callable( $callback ) ) {
array_unshift( $args, $widget_id, $check_urls );
ob_start();
call_user_func_array( $callback, $args );
call_user_func_array( $callback, wp_normalize_call_user_func_args( $args ) );
// Default lifetime in cache of 12 hours (same as the feeds).
set_transient( $cache_key, ob_get_flush(), 12 * HOUR_IN_SECONDS );
}
Expand Down
2 changes: 1 addition & 1 deletion src/wp-admin/includes/media.php
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ function wp_iframe( $content_func, ...$args ) {
</script>
<?php

call_user_func_array( $content_func, $args );
call_user_func_array( $content_func, wp_normalize_call_user_func_args( $args ) );

/** This action is documented in wp-admin/admin-footer.php */
do_action( 'admin_print_footer_scripts' );
Expand Down
2 changes: 1 addition & 1 deletion src/wp-admin/includes/post.php
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ function edit_post( $post_data = null ) {
$tax_object = get_taxonomy( $taxonomy );

if ( $tax_object && isset( $tax_object->meta_box_sanitize_cb ) ) {
$translated['tax_input'][ $taxonomy ] = call_user_func_array( $tax_object->meta_box_sanitize_cb, array( $taxonomy, $terms ) );
$translated['tax_input'][ $taxonomy ] = call_user_func_array( $tax_object->meta_box_sanitize_cb, wp_normalize_call_user_func_args( array( $taxonomy, $terms ) ) );
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/wp-admin/includes/widgets.php
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ function wp_widget_control( $sidebar_args ) {
<?php echo $before_widget_content; ?>
<?php
if ( isset( $control['callback'] ) ) {
$has_form = call_user_func_array( $control['callback'], $control['params'] );
$has_form = call_user_func_array( $control['callback'], wp_normalize_call_user_func_args( $control['params'] ) );
} else {
echo "\t\t<p>" . __( 'There are no options for this widget.' ) . "</p>\n";
}
Expand Down
4 changes: 2 additions & 2 deletions src/wp-admin/widgets-form.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@
}

ob_start();
call_user_func_array( $control['callback'], $control['params'] );
call_user_func_array( $control['callback'], wp_normalize_call_user_func_args( $control['params'] ) );
ob_end_clean();

break;
Expand Down Expand Up @@ -290,7 +290,7 @@
<div class="widget-inside">
<?php
if ( is_callable( $control_callback ) ) {
call_user_func_array( $control_callback, $control['params'] );
call_user_func_array( $control_callback, wp_normalize_call_user_func_args( $control['params'] ) );
} else {
echo '<p>' . __( 'There are no options for this widget.' ) . "</p>\n";
}
Expand Down
1 change: 1 addition & 0 deletions src/wp-includes/class-wp-block-bindings-source.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ public function __construct( string $name, array $source_properties ) {
* @return mixed The value of the source.
*/
public function get_value( array $source_args, $block_instance, string $attribute_name ) {
// Safe: Array is built internally with numeric keys, not from untrusted input.
$value = call_user_func_array( $this->get_value_callback, array( $source_args, $block_instance, $attribute_name ) );
/**
* Filters the output of a block bindings source.
Expand Down
4 changes: 2 additions & 2 deletions src/wp-includes/class-wp-customize-widgets.php
Original file line number Diff line number Diff line change
Expand Up @@ -1631,7 +1631,7 @@ public function call_widget_update( $widget_id ) {
foreach ( (array) $wp_registered_widget_updates as $name => $control ) {
if ( $name === $parsed_id['id_base'] && is_callable( $control['callback'] ) ) {
ob_start();
call_user_func_array( $control['callback'], $control['params'] );
call_user_func_array( $control['callback'], wp_normalize_call_user_func_args( $control['params'] ) );
ob_end_clean();
break;
}
Expand Down Expand Up @@ -1677,7 +1677,7 @@ public function call_widget_update( $widget_id ) {
ob_start();
$form = $wp_registered_widget_controls[ $widget_id ];
if ( $form ) {
call_user_func_array( $form['callback'], $form['params'] );
call_user_func_array( $form['callback'], wp_normalize_call_user_func_args( $form['params'] ) );
}
$form = ob_get_clean();

Expand Down
5 changes: 3 additions & 2 deletions src/wp-includes/class-wp-hook.php
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ public function apply_filters( $value, $args ) {
if ( 0 === $the_['accepted_args'] ) {
$value = call_user_func( $the_['function'] );
} elseif ( $the_['accepted_args'] >= $num_args ) {
$value = call_user_func_array( $the_['function'], $args );
$value = call_user_func_array( $the_['function'], wp_normalize_call_user_func_args( $args ) );
} else {
$value = call_user_func_array( $the_['function'], array_slice( $args, 0, $the_['accepted_args'] ) );
}
Expand Down Expand Up @@ -378,14 +378,15 @@ public function do_action( $args ) {
* @param array $args Arguments to pass to the hook callbacks. Passed by reference.
*/
public function do_all_hook( &$args ) {
$callback_args = wp_normalize_call_user_func_args( $args );
$nesting_level = $this->nesting_level++;
$this->iterations[ $nesting_level ] = $this->priorities;

do {
$priority = current( $this->iterations[ $nesting_level ] );

foreach ( $this->callbacks[ $priority ] as $the_ ) {
call_user_func_array( $the_['function'], $args );
call_user_func_array( $the_['function'], $callback_args );
}
} while ( false !== next( $this->iterations[ $nesting_level ] ) );

Expand Down
2 changes: 1 addition & 1 deletion src/wp-includes/class-wp-image-editor.php
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ protected function make_image( $filename, $callback, $arguments ) {
wp_mkdir_p( dirname( $filename ) );
}

$result = call_user_func_array( $callback, $arguments );
$result = call_user_func_array( $callback, wp_normalize_call_user_func_args( $arguments ) );

if ( $result && $stream ) {
$contents = ob_get_contents();
Expand Down
6 changes: 3 additions & 3 deletions src/wp-includes/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -7162,9 +7162,9 @@ function wp_find_hierarchy_loop_tortoise_hare( $callback, $start, $override = ar
while (
$tortoise
&&
( $evanescent_hare = $override[ $hare ] ?? call_user_func_array( $callback, array_merge( array( $hare ), $callback_args ) ) )
( $evanescent_hare = $override[ $hare ] ?? call_user_func_array( $callback, wp_normalize_call_user_func_args( array_merge( array( $hare ), $callback_args ) ) ) )
&&
( $hare = $override[ $evanescent_hare ] ?? call_user_func_array( $callback, array_merge( array( $evanescent_hare ), $callback_args ) ) )
( $hare = $override[ $evanescent_hare ] ?? call_user_func_array( $callback, wp_normalize_call_user_func_args( array_merge( array( $evanescent_hare ), $callback_args ) ) ) )
) {
if ( $_return_loop ) {
$return[ $tortoise ] = true;
Expand All @@ -7178,7 +7178,7 @@ function wp_find_hierarchy_loop_tortoise_hare( $callback, $start, $override = ar
}

// Increment tortoise by one step.
$tortoise = $override[ $tortoise ] ?? call_user_func_array( $callback, array_merge( array( $tortoise ), $callback_args ) );
$tortoise = $override[ $tortoise ] ?? call_user_func_array( $callback, wp_normalize_call_user_func_args( array_merge( array( $tortoise ), $callback_args ) ) );
}

return false;
Expand Down
23 changes: 23 additions & 0 deletions src/wp-includes/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -2047,3 +2047,26 @@ function wp_is_site_protected_by_basic_auth( $context = '' ) {
*/
return apply_filters( 'wp_is_site_protected_by_basic_auth', $is_protected, $context );
}

/**
* Normalizes an argument array for use with call_user_func_array() across PHP versions.
*
* PHP 8.0+ interprets string array keys as parameter names. In PHP 7.x, string keys were
* ignored when passing arguments positionally.
*
* @param array $args Arguments for the callback.
* @return array Positional argument list.
*/
function wp_normalize_call_user_func_args( $args ) {
if ( ! is_array( $args ) ) {
return $args;
}

foreach ( $args as $key => $unused ) {
if ( is_string( $key ) ) {
return array_values( $args );
}
}

return $args;
}
Original file line number Diff line number Diff line change
Expand Up @@ -184,16 +184,16 @@ public function get_item_permissions_check( $request ) {
*
* @since 6.9.0
*
* @param WP_Ability_Category $category The ability category object.
* @param WP_Ability_Category $item The ability category object.
* @param WP_REST_Request $request Request object.
* @return WP_REST_Response Response object.
*/
public function prepare_item_for_response( $category, $request ) {
public function prepare_item_for_response( $item, $request ) {
$data = array(
'slug' => $category->get_slug(),
'label' => $category->get_label(),
'description' => $category->get_description(),
'meta' => $category->get_meta(),
'slug' => $item->get_slug(),
'label' => $item->get_label(),
'description' => $item->get_description(),
'meta' => $item->get_meta(),
);

$context = $request['context'] ?? 'view';
Expand All @@ -206,13 +206,13 @@ public function prepare_item_for_response( $category, $request ) {
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$links = array(
'self' => array(
'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $category->get_slug() ) ),
'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $item->get_slug() ) ),
),
'collection' => array(
'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ),
),
'abilities' => array(
'href' => rest_url( sprintf( '%s/abilities?category=%s', $this->namespace, $category->get_slug() ) ),
'href' => rest_url( sprintf( '%s/abilities?category=%s', $this->namespace, $item->get_slug() ) ),
),
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,23 +295,23 @@ private function strip_internal_schema_keywords( array $schema ): array {
*
* @since 6.9.0
*
* @param WP_Ability $ability The ability object.
* @param WP_Ability $item The ability object.
* @param WP_REST_Request $request Request object.
* @return WP_REST_Response Response object.
*/
public function prepare_item_for_response( $ability, $request ) {
public function prepare_item_for_response( $item, $request ) {
$data = array(
'name' => $ability->get_name(),
'label' => $ability->get_label(),
'description' => $ability->get_description(),
'category' => $ability->get_category(),
'name' => $item->get_name(),
'label' => $item->get_label(),
'description' => $item->get_description(),
'category' => $item->get_category(),
'input_schema' => $this->strip_internal_schema_keywords(
$this->normalize_schema_empty_object_defaults( $ability->get_input_schema() )
$this->normalize_schema_empty_object_defaults( $item->get_input_schema() )
),
'output_schema' => $this->strip_internal_schema_keywords(
$this->normalize_schema_empty_object_defaults( $ability->get_output_schema() )
$this->normalize_schema_empty_object_defaults( $item->get_output_schema() )
),
'meta' => $ability->get_meta(),
'meta' => $item->get_meta(),
);

$context = $request['context'] ?? 'view';
Expand All @@ -324,15 +324,15 @@ public function prepare_item_for_response( $ability, $request ) {
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$links = array(
'self' => array(
'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $ability->get_name() ) ),
'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $item->get_name() ) ),
),
'collection' => array(
'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ),
),
);

$links['wp:action-run'] = array(
'href' => rest_url( sprintf( '%s/%s/%s/run', $this->namespace, $this->rest_base, $ability->get_name() ) ),
'href' => rest_url( sprintf( '%s/%s/%s/run', $this->namespace, $this->rest_base, $item->get_name() ) ),
);

$response->add_links( $links );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,12 +303,12 @@ protected function prepare_item_for_database( $request ) {
* @since 5.9.0
* @since 6.6.0 Added custom relative theme file URIs to `_links`.
*
* @param WP_Post $post Global Styles post object.
* @param WP_Post $item Global Styles post object.
* @param WP_REST_Request $request Request object.
* @return WP_REST_Response Response object.
*/
public function prepare_item_for_response( $post, $request ) {
$raw_config = json_decode( $post->post_content, true );
public function prepare_item_for_response( $item, $request ) {
$raw_config = json_decode( $item->post_content, true );
$is_global_styles_user_theme_json = isset( $raw_config['isGlobalStylesUserThemeJSON'] ) && true === $raw_config['isGlobalStylesUserThemeJSON'];
$config = array();
$theme_json = null;
Expand All @@ -322,20 +322,20 @@ public function prepare_item_for_response( $post, $request ) {
$data = array();

if ( rest_is_field_included( 'id', $fields ) ) {
$data['id'] = $post->ID;
$data['id'] = $item->ID;
}

if ( rest_is_field_included( 'title', $fields ) ) {
$data['title'] = array();
}
if ( rest_is_field_included( 'title.raw', $fields ) ) {
$data['title']['raw'] = $post->post_title;
$data['title']['raw'] = $item->post_title;
}
if ( rest_is_field_included( 'title.rendered', $fields ) ) {
add_filter( 'protected_title_format', array( $this, 'protected_title_format' ) );
add_filter( 'private_title_format', array( $this, 'protected_title_format' ) );

$data['title']['rendered'] = get_the_title( $post->ID );
$data['title']['rendered'] = get_the_title( $item->ID );

remove_filter( 'protected_title_format', array( $this, 'protected_title_format' ) );
remove_filter( 'private_title_format', array( $this, 'protected_title_format' ) );
Expand All @@ -357,7 +357,7 @@ public function prepare_item_for_response( $post, $request ) {
$response = rest_ensure_response( $data );

if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$links = $this->prepare_links( $post->ID );
$links = $this->prepare_links( $item->ID );

// Only return resolved URIs for get requests to user theme JSON.
if ( $theme_json ) {
Expand All @@ -369,7 +369,7 @@ public function prepare_item_for_response( $post, $request ) {

$response->add_links( $links );
if ( ! empty( $links['self']['href'] ) ) {
$actions = $this->get_available_actions( $post, $request );
$actions = $this->get_available_actions( $item, $request );
$self = $links['self']['href'];
foreach ( $actions as $rel ) {
$response->add_link( $rel, $self );
Expand Down
Loading
Loading