Changeset 46894 for trunk/src/wp-includes/formatting.php
- Timestamp:
- 12/12/2019 05:51:35 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/formatting.php
r46660 r46894 3149 3149 function wp_targeted_link_rel( $text ) { 3150 3150 // Don't run (more expensive) regex if no links with targets. 3151 if ( stripos( $text, 'target' ) !== false && stripos( $text, '<a ' ) !== false ) { 3152 if ( ! is_serialized( $text ) ) { 3153 $text = preg_replace_callback( '|<a\s([^>]*target\s*=[^>]*)>|i', 'wp_targeted_link_rel_callback', $text ); 3151 if ( stripos( $text, 'target' ) === false || stripos( $text, '<a ' ) === false || is_serialized( $text ) ) { 3152 return $text; 3153 } 3154 3155 $script_and_style_regex = '/<(script|style).*?<\/\\1>/si'; 3156 3157 preg_match_all( $script_and_style_regex, $text, $matches ); 3158 $extra_parts = $matches[0]; 3159 $html_parts = preg_split( $script_and_style_regex, $text ); 3160 3161 foreach ( $html_parts as &$part ) { 3162 $part = preg_replace_callback( '|<a\s([^>]*target\s*=[^>]*)>|i', 'wp_targeted_link_rel_callback', $part ); 3163 } 3164 3165 $text = ''; 3166 for ( $i = 0; $i < count( $html_parts ); $i++ ) { 3167 $text .= $html_parts[ $i ]; 3168 if ( isset( $extra_parts[ $i ] ) ) { 3169 $text .= $extra_parts[ $i ]; 3154 3170 } 3155 3171 } … … 3170 3186 */ 3171 3187 function wp_targeted_link_rel_callback( $matches ) { 3172 $link_html = $matches[1]; 3173 $rel_match = array(); 3188 $link_html = $matches[1]; 3189 $original_link_html = $link_html; 3190 3191 // Consider the html escaped if there are no unescaped quotes 3192 $is_escaped = ! preg_match( '/(^|[^\\\\])[\'"]/', $link_html ); 3193 if ( $is_escaped ) { 3194 // Replace only the quotes so that they are parsable by wp_kses_hair, leave the rest as is 3195 $link_html = preg_replace( '/\\\\([\'"])/', '$1', $link_html ); 3196 } 3197 3198 $atts = wp_kses_hair( $link_html, wp_allowed_protocols() ); 3174 3199 3175 3200 /** … … 3183 3208 $rel = apply_filters( 'wp_targeted_link_rel', 'noopener noreferrer', $link_html ); 3184 3209 3185 // Avoid additional regex if the filter removes rel values. 3186 if ( ! $rel ) { 3187 return "<a $link_html>"; 3188 } 3189 3190 // Value with delimiters, spaces around are optional. 3191 $attr_regex = '|rel\s*=\s*?(\\\\{0,1}["\'])(.*?)\\1|i'; 3192 preg_match( $attr_regex, $link_html, $rel_match ); 3193 3194 if ( empty( $rel_match[0] ) ) { 3195 // No delimiters, try with a single value and spaces, because `rel = va"lue` is totally fine... 3196 $attr_regex = '|rel\s*=(\s*)([^\s]*)|i'; 3197 preg_match( $attr_regex, $link_html, $rel_match ); 3198 } 3199 3200 if ( ! empty( $rel_match[0] ) ) { 3201 $parts = preg_split( '|\s+|', strtolower( $rel_match[2] ) ); 3202 $parts = array_map( 'esc_attr', $parts ); 3203 $needed = explode( ' ', $rel ); 3204 $parts = array_unique( array_merge( $parts, $needed ) ); 3205 $delimiter = trim( $rel_match[1] ) ? $rel_match[1] : '"'; 3206 $rel = 'rel=' . $delimiter . trim( implode( ' ', $parts ) ) . $delimiter; 3207 $link_html = str_replace( $rel_match[0], $rel, $link_html ); 3208 } elseif ( preg_match( '|target\s*=\s*?\\\\"|', $link_html ) ) { 3209 $link_html .= " rel=\\\"$rel\\\""; 3210 } elseif ( preg_match( '#(target|href)\s*=\s*?\'#', $link_html ) ) { 3211 $link_html .= " rel='$rel'"; 3212 } else { 3213 $link_html .= " rel=\"$rel\""; 3210 // Return early if no rel values to be added or if no actual target attribute 3211 if ( ! $rel || ! isset( $atts['target'] ) ) { 3212 return "<a $original_link_html>"; 3213 } 3214 3215 if ( isset( $atts['rel'] ) ) { 3216 $all_parts = preg_split( '/\s/', "{$atts['rel']['value']} $rel", -1, PREG_SPLIT_NO_EMPTY ); 3217 $rel = implode( ' ', array_unique( $all_parts ) ); 3218 } 3219 3220 $atts['rel']['whole'] = 'rel="' . esc_attr( $rel ) . '"'; 3221 $link_html = join( ' ', array_column( $atts, 'whole' ) ); 3222 3223 if ( $is_escaped ) { 3224 $link_html = preg_replace( '/[\'"]/', '\\\\$0', $link_html ); 3214 3225 } 3215 3226
Note: See TracChangeset
for help on using the changeset viewer.