From 4e18f78ced7877fe386019e3fb86666e1861c1c3 Mon Sep 17 00:00:00 2001 From: "K. Adam White" Date: Mon, 24 Feb 2020 18:05:12 +0000 Subject: [PATCH] REST API: Fix namespace shadowing issue in route matching logic. Following [47260] a namespace such as "test-ns" prevents any namespace such as "test-ns/v1" from being found when matching routes. While not best practice, this was an unintentional back-compat break; this patch restores the original behavior. Props david.binda, TimothyBlynJacobs. Fixes #48530. git-svn-id: https://develop.svn.wordpress.org/trunk@47351 602fd350-edb4-49c9-b593-d223f7449a82 --- .../rest-api/class-wp-rest-server.php | 11 ++++--- tests/phpunit/tests/rest-api/rest-server.php | 31 +++++++++++++++++++ 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/rest-api/class-wp-rest-server.php b/src/wp-includes/rest-api/class-wp-rest-server.php index 12de6c55f0..771c3b9fbe 100644 --- a/src/wp-includes/rest-api/class-wp-rest-server.php +++ b/src/wp-includes/rest-api/class-wp-rest-server.php @@ -879,16 +879,17 @@ class WP_REST_Server { $method = $request->get_method(); $path = $request->get_route(); - $routes = array(); + $with_namespace = array(); foreach ( $this->get_namespaces() as $namespace ) { - if ( 0 === strpos( ltrim( $path, '/' ), $namespace ) ) { - $routes = $this->get_routes( $namespace ); - break; + if ( 0 === strpos( trailingslashit( ltrim( $path, '/' ) ), $namespace ) ) { + $with_namespace[] = $this->get_routes( $namespace ); } } - if ( ! $routes ) { + if ( $with_namespace ) { + $routes = array_merge( ...$with_namespace ); + } else { $routes = $this->get_routes(); } diff --git a/tests/phpunit/tests/rest-api/rest-server.php b/tests/phpunit/tests/rest-api/rest-server.php index b724221891..8f178bff2b 100644 --- a/tests/phpunit/tests/rest-api/rest-server.php +++ b/tests/phpunit/tests/rest-api/rest-server.php @@ -1465,6 +1465,37 @@ class Tests_REST_Server extends WP_Test_REST_TestCase { } } + /** + * @ticket 48530 + */ + public function test_get_routes_no_namespace_overriding() { + register_rest_route( + 'test-ns', + '/test', + array( + 'methods' => array( 'GET' ), + 'callback' => function() { + return new WP_REST_Response( 'data', 204 ); + }, + ) + ); + register_rest_route( + 'test-ns/v1', + '/test', + array( + 'methods' => array( 'GET' ), + 'callback' => function() { + return new WP_REST_Response( 'data', 204 ); + }, + ) + ); + + $request = new WP_REST_Request( 'GET', '/test-ns/v1/test' ); + $response = rest_get_server()->dispatch( $request ); + + $this->assertEquals( 204, $response->get_status(), '/test-ns/v1/test' ); + } + public function _validate_as_integer_123( $value, $request, $key ) { if ( ! is_int( $value ) ) { return new WP_Error( 'some-error', 'This is not valid!' );