Ticket #10751: 10751-2.patch
| File 10751-2.patch, 21.7 KB (added by azaozz, 3 years ago) |
|---|
-
wp-admin/includes/template.php
1892 1892 1893 1893 if ( !( is_object( $user_object) && is_a( $user_object, 'WP_User' ) ) ) 1894 1894 $user_object = new WP_User( (int) $user_object ); 1895 $user_object = sanitize_user_object($user_object, 'display'); 1895 1896 $email = $user_object->user_email; 1896 1897 $url = $user_object->user_url; 1897 1898 $short_url = str_replace( 'http://', '', $url ); -
wp-admin/includes/user.php
25 25 $user_id = (int) func_get_arg( 0 ); 26 26 27 27 if ( isset( $_POST['role'] ) ) { 28 $new_role = sanitize_text_field( $_POST['role'] ); 28 29 // Don't let anyone with 'edit_users' (admins) edit their own role to something without it. 29 if ( $user_id != $current_user->id || $wp_roles->role_objects[$_POST['role']]->has_cap( 'edit_users' ) ) {30 if ( $user_id != $current_user->id || $wp_roles->role_objects[$new_role]->has_cap( 'edit_users' ) ) { 30 31 // If the new role isn't editable by the logged-in user die with error 31 32 $editable_roles = get_editable_roles(); 32 if ( !$editable_roles[$_POST['role']])33 if ( !$editable_roles[$new_role] ) 33 34 wp_die(__('You can’t give users that role.')); 34 35 35 36 $user = new WP_User( $user_id ); 36 $user->set_role( $ _POST['role']);37 $user->set_role( $new_role ); 37 38 } 38 39 } 39 40 } else { … … 64 65 $user = ''; 65 66 } 66 67 67 if ( isset( $_POST['user_login'] ))68 $user->user_login = esc_html( trim( $_POST['user_login'] ));68 if ( !$update && isset( $_POST['user_login'] ) ) 69 $user->user_login = sanitize_user($userdata['user_login'], true); 69 70 70 71 $pass1 = $pass2 = ''; 71 72 if ( isset( $_POST['pass1'] )) … … 74 75 $pass2 = $_POST['pass2']; 75 76 76 77 if ( isset( $_POST['role'] ) && current_user_can( 'edit_users' ) ) { 77 78 $new_role = sanitize_text_field( $_POST['role'] ); 78 79 // Don't let anyone with 'edit_users' (admins) edit their own role to something without it. 79 if( $user_id != $current_user->id || $wp_roles->role_objects[$ _POST['role']]->has_cap( 'edit_users' ))80 $user->role = $ _POST['role'];80 if( $user_id != $current_user->id || $wp_roles->role_objects[$new_role]->has_cap( 'edit_users' )) 81 $user->role = $new_role; 81 82 82 83 // If the new role isn't editable by the logged-in user die with error 83 84 $editable_roles = get_editable_roles(); 84 if ( !$editable_roles[$_POST['role']])85 if ( !$editable_roles[$new_role] ) 85 86 wp_die(__('You can’t give users that role.')); 86 87 } 87 88 88 89 if ( isset( $_POST['email'] )) 89 $user->user_email = esc_html( trim( $_POST['email'] ));90 $user->user_email = sanitize_text_field( $_POST['email'] ); 90 91 if ( isset( $_POST['url'] ) ) { 91 92 if ( empty ( $_POST['url'] ) || $_POST['url'] == 'http://' ) { 92 93 $user->user_url = ''; 93 94 } else { 94 $user->user_url = esc_url( trim( $_POST['url'] ));95 $user->user_url = sanitize_url( $_POST['url'] ); 95 96 $user->user_url = preg_match('/^(https?|ftps?|mailto|news|irc|gopher|nntp|feed|telnet):/is', $user->user_url) ? $user->user_url : 'http://'.$user->user_url; 96 97 } 97 98 } 98 if ( isset( $_POST['first_name'] )) 99 $user->first_name = esc_html( trim( $_POST['first_name'] )); 100 if ( isset( $_POST['last_name'] )) 101 $user->last_name = esc_html( trim( $_POST['last_name'] )); 102 if ( isset( $_POST['nickname'] )) 103 $user->nickname = esc_html( trim( $_POST['nickname'] )); 104 if ( isset( $_POST['display_name'] )) 105 $user->display_name = esc_html( trim( $_POST['display_name'] )); 106 if ( isset( $_POST['description'] )) 99 if ( isset( $_POST['first_name'] ) ) 100 $user->first_name = sanitize_text_field( $_POST['first_name'] ); 101 if ( isset( $_POST['last_name'] ) ) 102 $user->last_name = sanitize_text_field( $_POST['last_name'] ); 103 if ( isset( $_POST['nickname'] ) ) 104 $user->nickname = sanitize_text_field( $_POST['nickname'] ); 105 if ( isset( $_POST['display_name'] ) ) 106 $user->display_name = sanitize_text_field( $_POST['display_name'] ); 107 108 if ( isset( $_POST['description'] ) ) 107 109 $user->description = trim( $_POST['description'] ); 108 $user_contactmethods = _wp_get_user_contactmethods(); 109 foreach ( $user_contactmethods as $method => $name) {110 111 foreach ( _wp_get_user_contactmethods() as $method => $name ) { 110 112 if ( isset( $_POST[$method] )) 111 $user->$method = esc_html( trim( $_POST[$method] ));113 $user->$method = sanitize_text_field( $_POST[$method] ); 112 114 } 113 if ( !$update )114 $user->rich_editing = 'true'; // Default to true for new users.115 else if ( isset( $_POST['rich_editing'] ) )116 $user->rich_editing = $_POST['rich_editing'];117 else118 $user->rich_editing = 'true';119 115 120 $user->comment_shortcuts = isset( $_POST['comment_shortcuts'] )? $_POST['comment_shortcuts'] : ''; 116 if ( $update ) { 117 $user->rich_editing = isset( $_POST['rich_editing'] ) && 'false' == $_POST['rich_editing'] ? 'false' : 'true'; 118 $user->admin_color = isset( $_POST['admin_color'] ) ? sanitize_text_field( $_POST['admin_color'] ) : 'fresh'; 119 } 121 120 121 $user->comment_shortcuts = isset( $_POST['comment_shortcuts'] ) && 'true' == $_POST['comment_shortcuts'] ? 'true' : ''; 122 122 123 $user->use_ssl = 0; 123 124 if ( !empty($_POST['use_ssl']) ) 124 125 $user->use_ssl = 1; 125 126 126 if ( !$update )127 $user->admin_color = 'fresh'; // Default to fresh for new users.128 else if ( isset( $_POST['admin_color'] ) )129 $user->admin_color = $_POST['admin_color'];130 else131 $user->admin_color = 'fresh';132 133 127 $errors = new WP_Error(); 134 128 135 129 /* checking that username has been typed */ … … 159 153 if ( $pass1 != $pass2 ) 160 154 $errors->add( 'pass', __( '<strong>ERROR</strong>: Please enter the same password in the two password fields.' ), array( 'form-field' => 'pass1' ) ); 161 155 162 if ( !empty ( $pass1 ))156 if ( !empty( $pass1 ) ) 163 157 $user->user_pass = $pass1; 164 158 165 159 if ( !$update && !validate_username( $user->user_login ) ) 166 160 $errors->add( 'user_login', __( '<strong>ERROR</strong>: This username is invalid. Please enter a valid username.' )); 167 161 168 if ( !$update && username_exists( $user->user_login ))162 if ( !$update && username_exists( $user->user_login ) ) 169 163 $errors->add( 'user_login', __( '<strong>ERROR</strong>: This username is already registered. Please choose another one.' )); 170 164 171 165 /* checking e-mail address */ 172 if ( empty ( $user->user_email ) ) {166 if ( empty( $user->user_email ) ) { 173 167 $errors->add( 'empty_email', __( '<strong>ERROR</strong>: Please enter an e-mail address.' ), array( 'form-field' => 'email' ) ); 174 } elseif ( !is_email( $user->user_email ) ) {168 } elseif ( !is_email( $user->user_email ) ) { 175 169 $errors->add( 'invalid_email', __( '<strong>ERROR</strong>: The e-mail address isn’t correct.' ), array( 'form-field' => 'email' ) ); 176 170 } elseif ( ( $owner_id = email_exists($user->user_email) ) && $owner_id != $user->ID ) { 177 171 $errors->add( 'email_exists', __('<strong>ERROR</strong>: This email is already registered, please choose another one.'), array( 'form-field' => 'email' ) ); 178 172 } 179 173 180 // Allow plugins to return the reown errors.174 // Allow plugins to return their own errors. 181 175 do_action_ref_array('user_profile_update_errors', array ( &$errors, $update, &$user ) ); 182 176 183 177 if ( $errors->get_error_codes() ) 184 178 return $errors; 185 179 186 180 if ( $update ) { 187 $user_id = wp_update_user( get_object_vars( $user ) );181 $user_id = wp_update_user( get_object_vars( $user ) ); 188 182 } else { 189 $user_id = wp_insert_user( get_object_vars( $user ) );183 $user_id = wp_insert_user( get_object_vars( $user ) ); 190 184 wp_new_user_notification( $user_id, isset($_POST['send_password']) ? $pass1 : '' ); 191 185 } 192 186 return $user_id; … … 370 364 */ 371 365 function get_user_to_edit( $user_id ) { 372 366 $user = new WP_User( $user_id ); 373 $user->user_login = esc_attr($user->user_login);374 $user->user_email = esc_attr($user->user_email);375 $user->user_url = esc_url($user->user_url);376 $user->first_name = esc_attr($user->first_name);377 $user->last_name = esc_attr($user->last_name);378 $user->display_name = esc_attr($user->display_name);379 $user->nickname = esc_attr($user->nickname);380 367 381 368 $user_contactmethods = _wp_get_user_contactmethods(); 382 369 foreach ($user_contactmethods as $method => $name) { 383 $user->{$method} = isset( $user->{$method} ) && !empty( $user->{$method} ) ? esc_attr($user->{$method}) : ''; 370 if ( empty( $user->{$method} ) ) 371 $user->{$method} = ''; 384 372 } 385 386 $user->description = isset( $user->description ) && !empty( $user->description ) ? esc_html($user->description) : '';387 373 374 if ( empty($user->description) ) 375 $user->description = ''; 376 377 $user = sanitize_user_object($user, 'edit'); 378 388 379 return $user; 389 380 } 390 381 -
wp-admin/user-edit.php
284 284 <table class="form-table"> 285 285 <tr> 286 286 <th><label for="description"><?php _e('Biographical Info'); ?></label></th> 287 <td><textarea name="description" id="description" rows="5" cols="30"><?php echo $profileuser->description?></textarea><br />287 <td><textarea name="description" id="description" rows="5" cols="30"><?php echo esc_html($profileuser->description); ?></textarea><br /> 288 288 <span class="description"><?php _e('Share a little biographical information to fill out your profile. This may be shown publicly.'); ?></span></td> 289 289 </tr> 290 290 … … 311 311 } 312 312 ?> 313 313 314 <?php if ( count($profileuser->caps) > count($profileuser->roles) && apply_filters('additional_capabilities_display', true, $profileuser)):?>314 <?php if ( count($profileuser->caps) > count($profileuser->roles) && apply_filters('additional_capabilities_display', true, $profileuser) ) { ?> 315 315 <br class="clear" /> 316 316 <table width="99%" style="border: none;" cellspacing="2" cellpadding="3" class="editform"> 317 317 <tr> 318 318 <th scope="row"><?php _e('Additional Capabilities') ?></th> 319 319 <td><?php 320 320 $output = ''; 321 foreach($profileuser->caps as $cap => $value) { 322 if(!$wp_roles->is_role($cap)) { 323 if($output != '') $output .= ', '; 321 foreach ( $profileuser->caps as $cap => $value ) { 322 if ( !$wp_roles->is_role($cap) ) { 323 if ( $output != '' ) 324 $output .= ', '; 324 325 $output .= $value ? $cap : "Denied: {$cap}"; 325 326 } 326 327 } … … 328 329 ?></td> 329 330 </tr> 330 331 </table> 331 <?php endif;?>332 <?php } ?> 332 333 333 334 <p class="submit"> 334 335 <input type="hidden" name="action" value="update" /> -
wp-admin/users.php
385 385 </form> 386 386 </div> 387 387 388 <?php389 foreach ( array('user_login' => 'user_login', 'first_name' => 'user_firstname', 'last_name' => 'user_lastname', 'email' => 'user_email', 'url' => 'user_uri', 'role' => 'user_role') as $formpost => $var ) {390 $var = 'new_' . $var;391 $$var = isset($_REQUEST[$formpost]) ? esc_attr(stripslashes($_REQUEST[$formpost])) : '';392 }393 unset($name);394 ?>395 396 388 <br class="clear" /> 397 389 <?php 398 390 break; -
wp-includes/capabilities.php
449 449 var $last_name = ''; 450 450 451 451 /** 452 * The filter context applied to user data fields. 453 * 454 * @since 2.9.0 455 * @access private 456 * @var string 457 */ 458 var $filter = null; 459 460 /** 452 461 * PHP4 Constructor - Sets up the object properties. 453 462 * 454 463 * Retrieves the userdata and then assigns all of the data keys to direct -
wp-includes/default-filters.php
17 17 'pre_link_rel', 'pre_user_display_name', 'pre_user_first_name', 'pre_user_last_name', 18 18 'pre_user_nickname'); 19 19 foreach ( $filters as $filter ) { 20 add_filter($filter, 'strip_tags'); 21 add_filter($filter, 'trim'); 20 add_filter($filter, 'sanitize_text_field'); 22 21 add_filter($filter, 'wp_filter_kses'); 23 22 add_filter($filter, '_wp_specialchars', 30); 24 23 } 25 24 26 // Kses only for textarea saves27 $filters = array(' pre_term_description', 'pre_link_description', 'pre_link_notes', 'pre_user_description');25 // Strip, kses, special chars for string display 26 $filters = array('term_name', 'comment_author_name', 'link_name', 'link_target', 'link_rel', 'user_display_name', 'user_first_name', 'user_last_name', 'user_nickname'); 28 27 foreach ( $filters as $filter ) { 28 add_filter($filter, 'sanitize_text_field'); 29 29 add_filter($filter, 'wp_filter_kses'); 30 add_filter($filter, '_wp_specialchars', 30); 30 31 } 31 32 32 // Email 33 // Kses only for textarea saves and displays 34 $filters = array('pre_term_description', 'term_description', 'pre_link_description', 'link_description', 'pre_link_notes', 'link_notes', 'pre_user_description', 'user_description'); 35 foreach ( $filters as $filter ) { 36 add_filter($filter, 'wp_filter_kses'); 37 } 38 39 // Email saves 33 40 $filters = array('pre_comment_author_email', 'pre_user_email'); 34 41 foreach ( $filters as $filter ) { 35 42 add_filter($filter, 'trim'); … … 37 44 add_filter($filter, 'wp_filter_kses'); 38 45 } 39 46 47 // Email display 48 $filters = array('comment_author_email', 'user_email'); 49 foreach ( $filters as $filter ) { 50 add_filter($filter, 'sanitize_email'); 51 add_filter($filter, 'wp_filter_kses'); 52 } 53 40 54 // Save URL 41 55 $filters = array('pre_comment_author_url', 'pre_user_url', 'pre_link_url', 'pre_link_image', 42 56 'pre_link_rss'); 43 57 foreach ( $filters as $filter ) { 44 add_filter($filter, 'strip_tags'); 45 add_filter($filter, 'trim'); 58 add_filter($filter, 'wp_strip_all_tags'); 46 59 add_filter($filter, 'esc_url_raw'); 47 60 add_filter($filter, 'wp_filter_kses'); 48 61 } … … 50 63 // Display URL 51 64 $filters = array('user_url', 'link_url', 'link_image', 'link_rss', 'comment_url'); 52 65 foreach ( $filters as $filter ) { 53 add_filter($filter, 'strip_tags'); 54 add_filter($filter, 'trim'); 66 add_filter($filter, 'wp_strip_all_tags'); 55 67 add_filter($filter, 'esc_url'); 56 68 add_filter($filter, 'wp_filter_kses'); 57 69 } -
wp-includes/formatting.php
628 628 */ 629 629 function sanitize_user( $username, $strict = false ) { 630 630 $raw_username = $username; 631 $username = strip_tags($username);631 $username = wp_strip_all_tags($username); 632 632 // Kill octets 633 633 $username = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|', '', $username); 634 634 $username = preg_replace('/&.+?;/', '', $username); // Kill entities … … 2241 2241 $safe_text = wp_check_invalid_utf8( $text ); 2242 2242 $safe_text = _wp_specialchars( $safe_text, ENT_QUOTES ); 2243 2243 return apply_filters( 'esc_html', $safe_text, $text ); 2244 return $text;2245 2244 } 2246 2245 2247 2246 /** … … 2597 2596 * @return string The excerpt. 2598 2597 */ 2599 2598 function wp_html_excerpt( $str, $count ) { 2600 $str = strip_tags( $str);2599 $str = wp_strip_all_tags( $str, true ); 2601 2600 $str = mb_substr( $str, 0, $count ); 2602 2601 // remove part of an entity at the end 2603 2602 $str = preg_replace( '/&[^;\s]{0,6}$/', '', $str ); … … 2664 2663 create_function('$m', 'return _links_add_target($m, "' . $target . '");'), 2665 2664 $content); 2666 2665 } 2666 2667 2667 /** 2668 2668 * Callback to add a target attribute to all links in passed content. 2669 2669 * … … 2688 2688 return $str; 2689 2689 } 2690 2690 2691 /** 2692 * Properly strip all HTML tags including script and style 2693 * 2694 * @since 2.9.0 2695 * 2696 * @param string $string String containing HTML tags 2697 * @param bool $remove_breaks optional Whether to remove left over line breaks and white space chars 2698 * @return string The processed string. 2699 */ 2700 function wp_strip_all_tags($string, $remove_breaks = false) { 2701 $string = preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $string ); 2702 $string = strip_tags($string); 2703 2704 if ( $remove_breaks ) 2705 $string = preg_replace('/\s+/', ' ', $string); 2706 2707 return trim($string); 2708 } 2709 2710 /** 2711 * Sanitize a string from user input or from the db 2712 * 2713 * check for invalid UTF-8, 2714 * Convert single < characters to entity, 2715 * strip all tags, 2716 * remove line breaks, tabs and extra whitre space, 2717 * strip octets. 2718 * 2719 * @since 2.9 2720 * 2721 * @param string $str 2722 * @return string 2723 */ 2724 function sanitize_text_field($str) { 2725 $filtered = wp_check_invalid_utf8( $str ); 2726 2727 if ( strpos($filtered, '<') !== false ) { 2728 $filtered = wp_pre_kses_less_than( $filtered ); 2729 $filtered = wp_strip_all_tags( $filtered, true ); 2730 } else { 2731 $filtered = trim( preg_replace('/\s+/', ' ', $filtered) ); 2732 } 2733 2734 $match = array(); 2735 while ( preg_match('/%[a-f0-9]{2}/i', $filtered, $match) ) 2736 $filtered = str_replace($match[0], '', $filtered); 2737 2738 return apply_filters('sanitize_text_field', $filtered, $str); 2739 } 2740 2691 2741 ?> -
wp-includes/registration.php
169 169 170 170 $user_nicename_check = $wpdb->get_var( $wpdb->prepare("SELECT ID FROM $wpdb->users WHERE user_nicename = %s AND user_login != %s LIMIT 1" , $user_nicename, $user_login)); 171 171 172 if ( $user_nicename_check) {172 if ( $user_nicename_check ) { 173 173 $suffix = 2; 174 174 while ($user_nicename_check) { 175 175 $alt_user_nicename = $user_nicename . "-$suffix"; … … 198 198 update_usermeta( $user_id, 'comment_shortcuts', $comment_shortcuts); 199 199 update_usermeta( $user_id, 'admin_color', $admin_color); 200 200 update_usermeta( $user_id, 'use_ssl', $use_ssl); 201 foreach (_wp_get_user_contactmethods() as $method => $name) { 201 202 foreach ( _wp_get_user_contactmethods() as $method => $name ) { 202 203 if ( empty($$method) ) 203 204 $$method = ''; 204 205 205 206 update_usermeta( $user_id, $method, $$method ); 206 207 } 207 208 -
wp-includes/user.php
600 600 wp_cache_add($user->user_nicename, $user->ID, 'userslugs'); 601 601 } 602 602 603 /** 604 * Sanitize every user field. 605 * 606 * If the context is 'raw', then the user object or array will get minimal santization of the int fields. 607 * 608 * @since 2.3.0 609 * @uses sanitize_user_field() Used to sanitize the fields. 610 * 611 * @param object|array $user The User Object or Array 612 * @param string $context Optional, default is 'display'. How to sanitize user fields. 613 * @return object|array The now sanitized User Object or Array (will be the same type as $user) 614 */ 615 function sanitize_user_object($user, $context = 'display') { 616 if ( is_object($user) ) { 617 if ( !isset($user->ID) ) 618 $user->ID = 0; 619 if ( isset($user->data) ) 620 $vars = get_object_vars( $user->data ); 621 else 622 $vars = get_object_vars($user); 623 foreach ( array_keys($vars) as $field ) { 624 if ( is_array($user->$field) ) 625 continue; 626 $user->$field = sanitize_user_field($field, $user->$field, $user->ID, $context); 627 } 628 $user->filter = $context; 629 } else { 630 if ( !isset($user['ID']) ) 631 $user['ID'] = 0; 632 foreach ( array_keys($user) as $field ) 633 $user[$field] = sanitize_user_field($field, $user[$field], $user['ID'], $context); 634 $user['filter'] = $context; 635 } 636 637 return $user; 638 } 639 640 /** 641 * Sanitize user field based on context. 642 * 643 * Possible context values are: 'raw', 'edit', 'db', 'display', 'attribute' and 'js'. The 644 * 'display' context is used by default. 'attribute' and 'js' contexts are treated like 'display' 645 * when calling filters. 646 * 647 * @since 2.3.0 648 * @uses apply_filters() Calls 'edit_$field' and '${field_no_prefix}_edit_pre' passing $value and 649 * $user_id if $context == 'edit' and field name prefix == 'user_'. 650 * 651 * @uses apply_filters() Calls 'edit_user_$field' passing $value and $user_id if $context == 'db'. 652 * @uses apply_filters() Calls 'pre_$field' passing $value if $context == 'db' and field name prefix == 'user_'. 653 * @uses apply_filters() Calls '${field}_pre' passing $value if $context == 'db' and field name prefix != 'user_'. 654 * 655 * @uses apply_filters() Calls '$field' passing $value, $user_id and $context if $context == anything 656 * other than 'raw', 'edit' and 'db' and field name prefix == 'user_'. 657 * @uses apply_filters() Calls 'user_$field' passing $value if $context == anything other than 'raw', 658 * 'edit' and 'db' and field name prefix != 'user_'. 659 * 660 * @param string $field The user Object field name. 661 * @param mixed $value The user Object value. 662 * @param int $user_id user ID. 663 * @param string $context How to sanitize user fields. Looks for 'raw', 'edit', 'db', 'display', 664 * 'attribute' and 'js'. 665 * @return mixed Sanitized value. 666 */ 667 function sanitize_user_field($field, $value, $user_id, $context) { 668 $int_fields = array('ID'); 669 if ( in_array($field, $int_fields) ) 670 $value = (int) $value; 671 672 if ( 'raw' == $context ) 673 return $value; 674 675 if ( is_array($value) ) 676 return $value; 677 678 $prefixed = false; 679 if ( false !== strpos($field, 'user_') ) { 680 $prefixed = true; 681 $field_no_prefix = str_replace('user_', '', $field); 682 } 683 684 if ( 'edit' == $context ) { 685 if ( $prefixed ) { 686 $value = apply_filters("edit_$field", $value, $user_id); 687 } else { 688 $value = apply_filters("edit_user_$field", $value, $user_id); 689 } 690 691 if ( 'description' == $field ) 692 $value = esc_html($value); 693 else 694 $value = esc_attr($value); 695 } else if ( 'db' == $context ) { 696 if ( $prefixed ) { 697 $value = apply_filters("pre_$field", $value); 698 } else { 699 $value = apply_filters("pre_user_$field", $value); 700 } 701 } else { 702 // Use display filters by default. 703 if ( $prefixed ) 704 $value = apply_filters($field, $value, $user_id, $context); 705 else 706 $value = apply_filters("user_$field", $value, $user_id, $context); 707 } 708 709 if ( 'user_url' == $field ) 710 $value = esc_url($value); 711 712 if ( 'attribute' == $context ) 713 $value = esc_attr($value); 714 else if ( 'js' == $context ) 715 $value = esc_js($value); 716 717 return $value; 718 } 719 603 720 ?>
