From c2bc0e6836a7904ce8952f84ec9be723a6b0bdb9 Mon Sep 17 00:00:00 2001 From: Scott Taylor Date: Fri, 15 Nov 2013 02:46:10 +0000 Subject: [PATCH] Don't place smilies inside of pre or code tags. Don't skip smilie after a smilie with an 8 in it. Fix regular expression used for smiley translations to work when there is only one registered emoticon. Props solarissmoke, soulseekah, mdbitz, yonasy. ht to mdbitz for the Unit Tests and a comprehensive patch. Fixes #16448, #20124, #25303. Built from https://develop.svn.wordpress.org/trunk@26191 git-svn-id: http://core.svn.wordpress.org/trunk@26099 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/formatting.php | 32 +++++++++++++++++++++++++------- wp-includes/functions.php | 8 +++++--- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/wp-includes/formatting.php b/wp-includes/formatting.php index c120b61334..56aac4ca29 100644 --- a/wp-includes/formatting.php +++ b/wp-includes/formatting.php @@ -1793,18 +1793,36 @@ function translate_smiley( $matches ) { * @param string $text Content to convert smilies from text. * @return string Converted content with text smilies replaced with images. */ -function convert_smilies($text) { +function convert_smilies( $text ) { global $wp_smiliessearch; $output = ''; - if ( get_option('use_smilies') && !empty($wp_smiliessearch) ) { + if ( get_option( 'use_smilies' ) && ! empty( $wp_smiliessearch ) ) { // HTML loop taken from texturize function, could possible be consolidated - $textarr = preg_split("/(<.*>)/U", $text, -1, PREG_SPLIT_DELIM_CAPTURE); // capture the tags as well as in between - $stop = count($textarr);// loop stuff - for ($i = 0; $i < $stop; $i++) { + $textarr = preg_split( '/(<.*>)/U', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); // capture the tags as well as in between + $stop = count( $textarr );// loop stuff + + // Ignore proessing of specific tags + $tags_to_ignore = 'code|pre|style|script|textarea'; + $ignore_block_element = ''; + + for ( $i = 0; $i < $stop; $i++ ) { $content = $textarr[$i]; - if ((strlen($content) > 0) && ('<' != $content[0])) { // If it's not a tag - $content = preg_replace_callback($wp_smiliessearch, 'translate_smiley', $content); + + // If we're in an ignore block, wait until we find its closing tag + if ( '' == $ignore_block_element && preg_match( '/^<(' . $tags_to_ignore . ')>/', $content, $matches ) ) { + $ignore_block_element = $matches[1]; } + + // If it's not a tag and not in ignore block + if ( '' == $ignore_block_element && strlen( $content ) > 0 && '<' != $content[0] ) { + $content = preg_replace_callback( $wp_smiliessearch, 'translate_smiley', $content ); + } + + // did we exit ignore block + if ( '' != $ignore_block_element && '' == $content ) { + $ignore_block_element = ''; + } + $output .= $content; } } else { diff --git a/wp-includes/functions.php b/wp-includes/functions.php index 7d931bc6ea..aaecdd6bc0 100644 --- a/wp-includes/functions.php +++ b/wp-includes/functions.php @@ -2477,6 +2477,7 @@ function _mce_set_direction( $input ) { return $input; } + /** * Convert smiley code to the icon graphic file equivalent. * @@ -2566,7 +2567,7 @@ function smilies_init() { */ krsort($wpsmiliestrans); - $wp_smiliessearch = '/(?:\s|^)'; + $wp_smiliessearch = '/((?:\s|^)'; $subchar = ''; foreach ( (array) $wpsmiliestrans as $smiley => $img ) { @@ -2576,7 +2577,7 @@ function smilies_init() { // new subpattern? if ($firstchar != $subchar) { if ($subchar != '') { - $wp_smiliessearch .= ')|(?:\s|^)'; + $wp_smiliessearch .= ')(?=\s|$))|((?:\s|^)'; ; } $subchar = $firstchar; $wp_smiliessearch .= preg_quote($firstchar, '/') . '(?:'; @@ -2586,7 +2587,8 @@ function smilies_init() { $wp_smiliessearch .= preg_quote($rest, '/'); } - $wp_smiliessearch .= ')(?:\s|$)/m'; + $wp_smiliessearch .= ')(?=\s|$))/m'; + } /**