From e5a0c9da7f6e4fe4eea6d0560525f550b7e18985 Mon Sep 17 00:00:00 2001 From: Jorge Costa Date: Tue, 2 Dec 2025 22:11:01 +0000 Subject: [PATCH 1/4] Add: Unit test to validate core abilities schemas only include valid properties. --- .../abilities-api/wpRegisterCoreAbilities.php | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/tests/phpunit/tests/abilities-api/wpRegisterCoreAbilities.php b/tests/phpunit/tests/abilities-api/wpRegisterCoreAbilities.php index c89d6daf32cd6..c7e8d027b9504 100644 --- a/tests/phpunit/tests/abilities-api/wpRegisterCoreAbilities.php +++ b/tests/phpunit/tests/abilities-api/wpRegisterCoreAbilities.php @@ -174,4 +174,93 @@ public function test_core_get_environment_info_executes(): void { $this->assertArrayHasKey( 'wp_version', $ability_data ); $this->assertSame( $environment, $ability_data['environment'] ); } + + /** + * Tests that all core ability schemas only use valid JSON Schema keywords. + * + * This prevents regressions where invalid keywords like 'examples' are used + * in schema properties (not valid in JSON Schema draft-04 used by WordPress). + * + * @ticket 64098 + */ + public function test_core_abilities_schemas_use_only_valid_keywords(): void { + $allowed_keywords = rest_get_allowed_schema_keywords(); + // Add 'required' which is valid at the property level for draft-04. + $allowed_keywords[] = 'required'; + + $abilities = wp_get_abilities(); + + $this->assertNotEmpty( $abilities, 'Core abilities should be registered.' ); + + foreach ( $abilities as $ability ) { + $this->assert_schema_uses_valid_keywords( + $ability->get_input_schema(), + $allowed_keywords, + $ability->get_name() . ' input_schema' + ); + $this->assert_schema_uses_valid_keywords( + $ability->get_output_schema(), + $allowed_keywords, + $ability->get_name() . ' output_schema' + ); + } + } + + /** + * Recursively validates that a schema only uses allowed keywords. + * + * @param array|null $schema The schema to validate. + * @param array $allowed_keywords List of allowed schema keywords. + * @param string $context Context for error messages. + */ + private function assert_schema_uses_valid_keywords( $schema, array $allowed_keywords, string $context ): void { + if ( empty( $schema ) || ! is_array( $schema ) ) { + return; + } + + foreach ( $schema as $key => $value ) { + // Skip integer keys (array indices). + if ( is_int( $key ) ) { + continue; + } + + // These keywords contain nested schemas that we recurse into. + $nesting_keywords = array( 'properties', 'items', 'additionalProperties', 'patternProperties', 'anyOf', 'oneOf' ); + + if ( ! in_array( $key, $nesting_keywords, true ) && ! in_array( $key, $allowed_keywords, true ) ) { + $this->fail( "Invalid schema keyword '{$key}' found in {$context}. Valid keywords are: " . implode( ', ', $allowed_keywords ) ); + } + + // Recursively check nested schemas. + if ( 'properties' === $key && is_array( $value ) ) { + foreach ( $value as $prop_name => $prop_schema ) { + $this->assert_schema_uses_valid_keywords( + $prop_schema, + $allowed_keywords, + "{$context}.properties.{$prop_name}" + ); + } + } elseif ( 'items' === $key && is_array( $value ) ) { + $this->assert_schema_uses_valid_keywords( + $value, + $allowed_keywords, + "{$context}.items" + ); + } elseif ( ( 'anyOf' === $key || 'oneOf' === $key ) && is_array( $value ) ) { + foreach ( $value as $index => $sub_schema ) { + $this->assert_schema_uses_valid_keywords( + $sub_schema, + $allowed_keywords, + "{$context}.{$key}[{$index}]" + ); + } + } elseif ( 'additionalProperties' === $key && is_array( $value ) ) { + $this->assert_schema_uses_valid_keywords( + $value, + $allowed_keywords, + "{$context}.additionalProperties" + ); + } + } + } } From 471fb3087bcc10b3ad0b278ce9090a51af0875fa Mon Sep 17 00:00:00 2001 From: Jorge Costa Date: Fri, 5 Dec 2025 13:55:13 +0000 Subject: [PATCH 2/4] Update tests/phpunit/tests/abilities-api/wpRegisterCoreAbilities.php Co-authored-by: Weston Ruter --- tests/phpunit/tests/abilities-api/wpRegisterCoreAbilities.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/abilities-api/wpRegisterCoreAbilities.php b/tests/phpunit/tests/abilities-api/wpRegisterCoreAbilities.php index c7e8d027b9504..db72fdece89cb 100644 --- a/tests/phpunit/tests/abilities-api/wpRegisterCoreAbilities.php +++ b/tests/phpunit/tests/abilities-api/wpRegisterCoreAbilities.php @@ -210,7 +210,7 @@ public function test_core_abilities_schemas_use_only_valid_keywords(): void { * Recursively validates that a schema only uses allowed keywords. * * @param array|null $schema The schema to validate. - * @param array $allowed_keywords List of allowed schema keywords. + * @param string[] $allowed_keywords List of allowed schema keywords. * @param string $context Context for error messages. */ private function assert_schema_uses_valid_keywords( $schema, array $allowed_keywords, string $context ): void { From 2c5e456ae6c2507ad937c5d13ba93745bafdbada Mon Sep 17 00:00:00 2001 From: Jorge Costa Date: Sat, 6 Dec 2025 10:29:47 +0000 Subject: [PATCH 3/4] Update tests/phpunit/tests/abilities-api/wpRegisterCoreAbilities.php Co-authored-by: Weston Ruter --- tests/phpunit/tests/abilities-api/wpRegisterCoreAbilities.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/abilities-api/wpRegisterCoreAbilities.php b/tests/phpunit/tests/abilities-api/wpRegisterCoreAbilities.php index db72fdece89cb..547214360d9bf 100644 --- a/tests/phpunit/tests/abilities-api/wpRegisterCoreAbilities.php +++ b/tests/phpunit/tests/abilities-api/wpRegisterCoreAbilities.php @@ -213,7 +213,7 @@ public function test_core_abilities_schemas_use_only_valid_keywords(): void { * @param string[] $allowed_keywords List of allowed schema keywords. * @param string $context Context for error messages. */ - private function assert_schema_uses_valid_keywords( $schema, array $allowed_keywords, string $context ): void { + private function assert_schema_uses_valid_keywords( ?array $schema, array $allowed_keywords, string $context ): void { if ( empty( $schema ) || ! is_array( $schema ) ) { return; } From 494308d32eb4318b1105bdc3469d5b8d73bbd605 Mon Sep 17 00:00:00 2001 From: Jorge Costa Date: Sat, 6 Dec 2025 10:30:00 +0000 Subject: [PATCH 4/4] Update tests/phpunit/tests/abilities-api/wpRegisterCoreAbilities.php Co-authored-by: Weston Ruter --- tests/phpunit/tests/abilities-api/wpRegisterCoreAbilities.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/abilities-api/wpRegisterCoreAbilities.php b/tests/phpunit/tests/abilities-api/wpRegisterCoreAbilities.php index 547214360d9bf..2221baf1ff7eb 100644 --- a/tests/phpunit/tests/abilities-api/wpRegisterCoreAbilities.php +++ b/tests/phpunit/tests/abilities-api/wpRegisterCoreAbilities.php @@ -214,7 +214,7 @@ public function test_core_abilities_schemas_use_only_valid_keywords(): void { * @param string $context Context for error messages. */ private function assert_schema_uses_valid_keywords( ?array $schema, array $allowed_keywords, string $context ): void { - if ( empty( $schema ) || ! is_array( $schema ) ) { + if ( null === $schema ) { return; }