Changeset 42000
- Timestamp:
- 10/24/2017 09:04:50 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/rest-api.php
r41744 r42000 1107 1107 1108 1108 foreach ( $value as $property => $v ) { 1109 if ( !isset( $args['properties'][ $property ] ) ) {1110 continue;1111 }1112 $is_valid = rest_validate_value_from_schema( $v, $args['properties'][ $property ], $param . '[' . $property . ']' );1113 1114 if ( is_wp_error( $is_valid )) {1115 return $is_valid;1109 if ( isset( $args['properties'][ $property ] ) ) { 1110 $is_valid = rest_validate_value_from_schema( $v, $args['properties'][ $property ], $param . '[' . $property . ']' ); 1111 if ( is_wp_error( $is_valid ) ) { 1112 return $is_valid; 1113 } 1114 } elseif ( isset( $args['additionalProperties'] ) && false === $args['additionalProperties'] ) { 1115 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not a valid property of Object.' ), $property ) ); 1116 1116 } 1117 1117 } … … 1247 1247 1248 1248 foreach ( $value as $property => $v ) { 1249 if ( ! isset( $args['properties'][ $property ] ) ) { 1249 if ( isset( $args['properties'][ $property ] ) ) { 1250 $value[ $property ] = rest_sanitize_value_from_schema( $v, $args['properties'][ $property ] ); 1251 } elseif ( isset( $args['additionalProperties'] ) && false === $args['additionalProperties'] ) { 1250 1252 unset( $value[ $property ] ); 1251 continue;1252 1253 } 1253 $value[ $property ] = rest_sanitize_value_from_schema( $v, $args['properties'][ $property ] );1254 1254 } 1255 1255 -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php
r41758 r42000 546 546 } 547 547 548 foreach ( array( 'type', 'format', 'enum', 'items', 'properties' ) as $schema_prop ) {548 foreach ( array( 'type', 'format', 'enum', 'items', 'properties', 'additionalProperties' ) as $schema_prop ) { 549 549 if ( isset( $params[ $schema_prop ] ) ) { 550 550 $endpoint_args[ $field_id ][ $schema_prop ] = $params[ $schema_prop ]; -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-settings-controller.php
r41758 r42000 249 249 } 250 250 251 $rest_args['schema'] = $this->set_additional_properties_to_false( $rest_args['schema'] ); 252 251 253 $rest_options[ $rest_args['name'] ] = $rest_args; 252 254 } … … 302 304 return rest_parse_request_arg( $value, $request, $param ); 303 305 } 306 307 /** 308 * Recursively add additionalProperties = false to all objects in a schema. 309 * 310 * This is need to restrict properties of objects in settings values to only 311 * registered items, as the REST API will allow additional properties by 312 * default. 313 * 314 * @since 4.9.0 315 * 316 * @param array $schema The schema array. 317 * @return array 318 */ 319 protected function set_additional_properties_to_false( $schema ) { 320 switch ( $schema['type'] ) { 321 case 'object': 322 foreach ( $schema['properties'] as $key => $child_schema ) { 323 $schema['properties'][ $key ] = $this->set_additional_properties_to_false( $child_schema ); 324 } 325 $schema['additionalProperties'] = false; 326 break; 327 case 'array': 328 $schema['items'] = $this->set_additional_properties_to_false( $schema['items'] ); 329 break; 330 } 331 332 return $schema; 333 } 304 334 } -
trunk/tests/phpunit/tests/rest-api/rest-schema-sanitization.php
r41727 r42000 158 158 $this->assertEquals( array( 'a' => 1 ), rest_sanitize_value_from_schema( array( 'a' => 1 ), $schema ) ); 159 159 $this->assertEquals( array( 'a' => 1 ), rest_sanitize_value_from_schema( array( 'a' => '1' ), $schema ) ); 160 $this->assertEquals( array( 'a' => 1, 'b' => 1 ), rest_sanitize_value_from_schema( array( 'a' => '1', 'b' => 1 ), $schema ) ); 161 } 162 163 public function test_type_object_strips_additional_properties() { 164 $schema = array( 165 'type' => 'object', 166 'properties' => array( 167 'a' => array( 168 'type' => 'number', 169 ), 170 ), 171 'additionalProperties' => false, 172 ); 173 $this->assertEquals( array( 'a' => 1 ), rest_sanitize_value_from_schema( array( 'a' => 1 ), $schema ) ); 174 $this->assertEquals( array( 'a' => 1 ), rest_sanitize_value_from_schema( array( 'a' => '1' ), $schema ) ); 175 $this->assertEquals( array( 'a' => 1 ), rest_sanitize_value_from_schema( array( 'a' => '1', 'b' => 1 ), $schema ) ); 160 176 } 161 177 … … 196 212 'b' => 1, 197 213 'c' => 3, 198 ), 214 'd' => '1', 215 ), 216 'b' => 1, 199 217 ), 200 218 rest_sanitize_value_from_schema( -
trunk/tests/phpunit/tests/rest-api/rest-schema-validation.php
r41727 r42000 187 187 'properties' => array( 188 188 'a' => array( 189 'type' => 'number' 189 'type' => 'number', 190 190 ), 191 191 ), 192 192 ); 193 193 $this->assertTrue( rest_validate_value_from_schema( array( 'a' => 1 ), $schema ) ); 194 $this->assertTrue( rest_validate_value_from_schema( array( 'a' => 1, 'b' => 2 ), $schema ) ); 194 195 $this->assertWPError( rest_validate_value_from_schema( array( 'a' => 'invalid' ), $schema ) ); 196 } 197 198 public function test_type_object_additional_properties_false() { 199 $schema = array( 200 'type' => 'object', 201 'properties' => array( 202 'a' => array( 203 'type' => 'number', 204 ), 205 ), 206 'additionalProperties' => false, 207 ); 208 $this->assertTrue( rest_validate_value_from_schema( array( 'a' => 1 ), $schema ) ); 209 $this->assertWPError( rest_validate_value_from_schema( array( 'a' => 1, 'b' => 2 ), $schema ) ); 195 210 } 196 211 -
trunk/tests/phpunit/tests/rest-api/rest-settings-controller.php
r41758 r42000 191 191 ) ); 192 192 193 // We have to re-register the route, as the args changes based off registered settings. 194 $this->server->override_by_default = true; 195 $this->endpoint->register_routes(); 196 193 197 // Object is cast to correct types. 194 198 update_option( 'mycustomsetting', array( 'a' => '1' ) ); … … 210 214 $response = $this->server->dispatch( $request ); 211 215 $data = $response->get_data(); 212 $this->assertEquals( array( 'a' => 1 ), $data['mycustomsetting'] );216 $this->assertEquals( null, $data['mycustomsetting'] ); 213 217 214 218 unregister_setting( 'somegroup', 'mycustomsetting' ); … … 373 377 } 374 378 379 public function test_update_item_with_nested_object() { 380 register_setting( 'somegroup', 'mycustomsetting', array( 381 'show_in_rest' => array( 382 'schema' => array( 383 'type' => 'object', 384 'properties' => array( 385 'a' => array( 386 'type' => 'object', 387 'properties' => array( 388 'b' => array( 389 'type' => 'number', 390 ), 391 ), 392 ), 393 ), 394 ), 395 ), 396 'type' => 'object', 397 ) ); 398 399 // We have to re-register the route, as the args changes based off registered settings. 400 $this->server->override_by_default = true; 401 $this->endpoint->register_routes(); 402 wp_set_current_user( self::$administrator ); 403 404 $request = new WP_REST_Request( 'PUT', '/wp/v2/settings' ); 405 $request->set_param( 'mycustomsetting', array( 'a' => array( 'b' => 1, 'c' => 1 ) ) ); 406 $response = $this->server->dispatch( $request ); 407 $this->assertErrorResponse( 'rest_invalid_param', $response, 400 ); 408 } 409 375 410 public function test_update_item_with_object() { 376 411 register_setting( 'somegroup', 'mycustomsetting', array( … … 408 443 $this->assertEquals( array(), get_option( 'mycustomsetting' ) ); 409 444 445 // Provide more keys. 446 $request = new WP_REST_Request( 'PUT', '/wp/v2/settings' ); 447 $request->set_param( 'mycustomsetting', array( 'a' => 1, 'b' => 2 ) ); 448 $response = $this->server->dispatch( $request ); 449 450 $this->assertErrorResponse( 'rest_invalid_param', $response, 400 ); 451 410 452 // Setting an invalid object. 411 453 $request = new WP_REST_Request( 'PUT', '/wp/v2/settings' );
Note: See TracChangeset
for help on using the changeset viewer.