Changeset 46907 for branches/5.1/src/wp-includes/formatting.php
- Timestamp:
- 12/12/2019 06:36:20 PM (6 years ago)
- Location:
- branches/5.1
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
src/wp-includes/formatting.php (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/5.1
- Property svn:mergeinfo changed
/trunk merged: 46893-46896
- Property svn:mergeinfo changed
-
branches/5.1/src/wp-includes/formatting.php
r45992 r46907 3042 3042 function wp_targeted_link_rel( $text ) { 3043 3043 // Don't run (more expensive) regex if no links with targets. 3044 if ( stripos( $text, 'target' ) !== false && stripos( $text, '<a ' ) !== false ) { 3045 $text = preg_replace_callback( '|<a\s([^>]*target\s*=[^>]*)>|i', 'wp_targeted_link_rel_callback', $text ); 3044 if ( stripos( $text, 'target' ) === false || stripos( $text, '<a ' ) === false || is_serialized( $text ) ) { 3045 return $text; 3046 } 3047 3048 $script_and_style_regex = '/<(script|style).*?<\/\\1>/si'; 3049 3050 preg_match_all( $script_and_style_regex, $text, $matches ); 3051 $extra_parts = $matches[0]; 3052 $html_parts = preg_split( $script_and_style_regex, $text ); 3053 3054 foreach ( $html_parts as &$part ) { 3055 $part = preg_replace_callback( '|<a\s([^>]*target\s*=[^>]*)>|i', 'wp_targeted_link_rel_callback', $part ); 3056 } 3057 3058 $text = ''; 3059 for ( $i = 0; $i < count( $html_parts ); $i++ ) { 3060 $text .= $html_parts[ $i ]; 3061 if ( isset( $extra_parts[ $i ] ) ) { 3062 $text .= $extra_parts[ $i ]; 3063 } 3046 3064 } 3047 3065 … … 3059 3077 */ 3060 3078 function wp_targeted_link_rel_callback( $matches ) { 3061 $link_html = $matches[1]; 3062 $rel_match = array(); 3079 $link_html = $matches[1]; 3080 $original_link_html = $link_html; 3081 3082 // Consider the html escaped if there are no unescaped quotes 3083 $is_escaped = ! preg_match( '/(^|[^\\\\])[\'"]/', $link_html ); 3084 if ( $is_escaped ) { 3085 // Replace only the quotes so that they are parsable by wp_kses_hair, leave the rest as is 3086 $link_html = preg_replace( '/\\\\([\'"])/', '$1', $link_html ); 3087 } 3088 3089 $atts = wp_kses_hair( $link_html, wp_allowed_protocols() ); 3063 3090 3064 3091 /** … … 3072 3099 $rel = apply_filters( 'wp_targeted_link_rel', 'noopener noreferrer', $link_html ); 3073 3100 3074 // Avoid additional regex if the filter removes rel values. 3075 if ( ! $rel ) { 3076 return "<a $link_html>"; 3077 } 3078 3079 // Value with delimiters, spaces around are optional. 3080 $attr_regex = '|rel\s*=\s*?(\\\\{0,1}["\'])(.*?)\\1|i'; 3081 preg_match( $attr_regex, $link_html, $rel_match ); 3082 3083 if ( empty( $rel_match[0] ) ) { 3084 // No delimiters, try with a single value and spaces, because `rel = va"lue` is totally fine... 3085 $attr_regex = '|rel\s*=(\s*)([^\s]*)|i'; 3086 preg_match( $attr_regex, $link_html, $rel_match ); 3087 } 3088 3089 if ( ! empty( $rel_match[0] ) ) { 3090 $parts = preg_split( '|\s+|', strtolower( $rel_match[2] ) ); 3091 $parts = array_map( 'esc_attr', $parts ); 3092 $needed = explode( ' ', $rel ); 3093 $parts = array_unique( array_merge( $parts, $needed ) ); 3094 $delimiter = trim( $rel_match[1] ) ? $rel_match[1] : '"'; 3095 $rel = 'rel=' . $delimiter . trim( implode( ' ', $parts ) ) . $delimiter; 3096 $link_html = str_replace( $rel_match[0], $rel, $link_html ); 3097 } else { 3098 $link_html .= " rel=\"$rel\""; 3101 // Return early if no rel values to be added or if no actual target attribute 3102 if ( ! $rel || ! isset( $atts['target'] ) ) { 3103 return "<a $original_link_html>"; 3104 } 3105 3106 if ( isset( $atts['rel'] ) ) { 3107 $all_parts = preg_split( '/\s/', "{$atts['rel']['value']} $rel", -1, PREG_SPLIT_NO_EMPTY ); 3108 $rel = implode( ' ', array_unique( $all_parts ) ); 3109 } 3110 3111 $atts['rel']['whole'] = 'rel="' . esc_attr( $rel ) . '"'; 3112 $link_html = join( ' ', array_column( $atts, 'whole' ) ); 3113 3114 if ( $is_escaped ) { 3115 $link_html = preg_replace( '/[\'"]/', '\\\\$0', $link_html ); 3099 3116 } 3100 3117 … … 4798 4815 4799 4816 /** 4817 * Remove non-allowable HTML from parsed block attribute values when filtering 4818 * in the post context. 4819 * 4820 * @since 5.3.1 4821 * 4822 * @param string $string Content to be run through KSES. 4823 * @param array[]|string $allowed_html An array of allowed HTML elements 4824 * and attributes, or a context name 4825 * such as 'post'. 4826 * @param string[] $allowed_protocols Array of allowed URL protocols. 4827 * @return string Filtered text to run through KSES. 4828 */ 4829 function wp_pre_kses_block_attributes( $string, $allowed_html, $allowed_protocols ) { 4830 /* 4831 * `filter_block_content` is expected to call `wp_kses`. Temporarily remove 4832 * the filter to avoid recursion. 4833 */ 4834 remove_filter( 'pre_kses', 'wp_pre_kses_block_attributes', 10 ); 4835 $string = filter_block_content( $string, $allowed_html, $allowed_protocols ); 4836 add_filter( 'pre_kses', 'wp_pre_kses_block_attributes', 10, 3 ); 4837 4838 return $string; 4839 } 4840 4841 /** 4800 4842 * WordPress implementation of PHP sprintf() with filters. 4801 4843 *
Note: See TracChangeset
for help on using the changeset viewer.