Skip to content

Commit 6c17b03

Browse files
committed
REST API: Ensure args is an array of arrays in register_rest_route().
When calling `register_rest_route()`, the `args` parameter for a route should be an array of arrays. However, some plugins/themes have passed an array of strings or key-value pairs which produces a PHP warning when `array_intersect_key` is used to filter the array keys based on an allowed list of schema keywords. This change adds a check of the `args` parameter to ensure it's an array of arrays, presenting a `_doing_it_wrong` if any element of `args` is not an array and restructuring to an array of arrays. This change also adds a unit test for the incorrect usage described above, expecting that a `_doing_it_wrong` is produced. Props slaFFik, desrosj, apermo, AndrewNZ, aristath, poena, dovyp, timothyblynjacobs, Hinjiriyo, johnmark8080, nateallen. Fixes #51986. git-svn-id: https://develop.svn.wordpress.org/trunk@54339 602fd350-edb4-49c9-b593-d223f7449a82
1 parent af33442 commit 6c17b03

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

src/wp-includes/rest-api.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,18 @@ function register_rest_route( $namespace, $route, $args = array(), $override = f
103103
'5.5.0'
104104
);
105105
}
106+
107+
if ( count( array_filter( $arg_group['args'], 'is_array' ) ) !== count( $arg_group['args'] ) ) {
108+
_doing_it_wrong(
109+
__FUNCTION__,
110+
sprintf(
111+
/* translators: %s: The REST API route being registered. */
112+
__( 'REST API $args should be an array of arrays. Non-array value detected for %s.' ),
113+
'<code>' . $clean_namespace . '/' . trim( $route, '/' ) . '</code>'
114+
),
115+
'6.1.0'
116+
);
117+
}
106118
}
107119

108120
$full_route = '/' . $clean_namespace . '/' . trim( $route, '/' );

src/wp-includes/rest-api/class-wp-rest-server.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,6 +1513,11 @@ public function get_data_for_route( $route, $callbacks, $context = 'view' ) {
15131513
$endpoint_data['args'] = array();
15141514

15151515
foreach ( $callback['args'] as $key => $opts ) {
1516+
if ( is_string( $opts ) ) {
1517+
$opts = array( $opts => 0 );
1518+
} elseif ( ! is_array( $opts ) ) {
1519+
$opts = array();
1520+
}
15161521
$arg_data = array_intersect_key( $opts, $allowed_schema_keywords );
15171522
$arg_data['required'] = ! empty( $opts['required'] );
15181523

tests/phpunit/tests/rest-api.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2518,4 +2518,23 @@ public function test_rest_preload_api_request_fields() {
25182518
array( 'description', '_links' )
25192519
);
25202520
}
2521+
2522+
/**
2523+
* @ticket 51986
2524+
*/
2525+
public function test_route_args_is_array_of_arrays() {
2526+
$this->setExpectedIncorrectUsage( 'register_rest_route' );
2527+
2528+
$registered = register_rest_route(
2529+
'my-ns/v1',
2530+
'/my-route',
2531+
array(
2532+
'callback' => '__return_true',
2533+
'permission_callback' => '__return_true',
2534+
'args' => array( 'pattern' ),
2535+
)
2536+
);
2537+
2538+
$this->assertTrue( $registered );
2539+
}
25212540
}

0 commit comments

Comments
 (0)