diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php index 8b385f63be..11eb2b71ad 100644 --- a/src/wp-includes/rest-api.php +++ b/src/wp-includes/rest-api.php @@ -44,6 +44,12 @@ function register_rest_route( $namespace, $route, $args = array(), $override = f return false; } + $clean_namespace = trim( $namespace, '/' ); + + if ( $clean_namespace !== $namespace ) { + _doing_it_wrong( __FUNCTION__, __( 'Namespace must not start or end with a slash.' ), '5.4.2' ); + } + if ( ! did_action( 'rest_api_init' ) ) { _doing_it_wrong( 'register_rest_route', @@ -84,8 +90,8 @@ function register_rest_route( $namespace, $route, $args = array(), $override = f $arg_group['args'] = array_merge( $common_args, $arg_group['args'] ); } - $full_route = '/' . trim( $namespace, '/' ) . '/' . trim( $route, '/' ); - rest_get_server()->register_route( $namespace, $full_route, $args, $override ); + $full_route = '/' . $clean_namespace . '/' . trim( $route, '/' ); + rest_get_server()->register_route( $clean_namespace, $full_route, $args, $override ); return true; } diff --git a/tests/phpunit/tests/rest-api.php b/tests/phpunit/tests/rest-api.php index bc05e7ed38..ac3274ec7a 100644 --- a/tests/phpunit/tests/rest-api.php +++ b/tests/phpunit/tests/rest-api.php @@ -985,6 +985,26 @@ class Tests_REST_API extends WP_UnitTestCase { $this->assertEquals( $expected, rest_filter_response_by_context( $data, $schema, 'view' ) ); } + /** + * @ticket 49749 + */ + public function test_register_route_with_invalid_namespace() { + $this->setExpectedIncorrectUsage( 'register_rest_route' ); + + register_rest_route( + '/my-namespace/v1/', + '/my-route', + array( + 'callback' => '__return_true', + ) + ); + + $routes = rest_get_server()->get_routes( 'my-namespace/v1' ); + $this->assertCount( 2, $routes ); + + $this->assertTrue( rest_do_request( '/my-namespace/v1/my-route' )->get_data() ); + } + public function _dp_rest_filter_response_by_context() { return array( 'default' => array(