diff --git a/src/wp-includes/formatting.php b/src/wp-includes/formatting.php index 8aa6ad721d..a36129767f 100644 --- a/src/wp-includes/formatting.php +++ b/src/wp-includes/formatting.php @@ -1912,7 +1912,7 @@ function translate_smiley( $matches ) { */ $src_url = apply_filters( 'smilies_src', includes_url( "images/smilies/$img" ), $img, site_url() ); - return sprintf( ' %s ', esc_url( $src_url ), esc_attr( $smiley ) ); + return sprintf( '%s', esc_url( $src_url ), esc_attr( $smiley ) ); } /** diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index c62036f7e8..db399cf1e6 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -2713,7 +2713,10 @@ function smilies_init() { */ krsort($wpsmiliestrans); - $wp_smiliessearch = '/((?:\s|^)'; + $spaces = wp_spaces_regexp(); + + // Begin first "subpattern" + $wp_smiliessearch = '/(?<=' . $spaces . '|^)'; $subchar = ''; foreach ( (array) $wpsmiliestrans as $smiley => $img ) { @@ -2723,7 +2726,8 @@ function smilies_init() { // new subpattern? if ($firstchar != $subchar) { if ($subchar != '') { - $wp_smiliessearch .= ')(?=\s|$))|((?:\s|^)'; ; + $wp_smiliessearch .= ')(?=' . $spaces . '|$)'; // End previous "subpattern" + $wp_smiliessearch .= '|(?<=' . $spaces . '|^)'; // Begin another "subpattern" } $subchar = $firstchar; $wp_smiliessearch .= preg_quote($firstchar, '/') . '(?:'; @@ -2733,7 +2737,7 @@ function smilies_init() { $wp_smiliessearch .= preg_quote($rest, '/'); } - $wp_smiliessearch .= ')(?=\s|$))/m'; + $wp_smiliessearch .= ')(?=' . $spaces . '|$)/m'; } @@ -4419,4 +4423,4 @@ function wp_validate_boolean( $var ) { } return (bool) $var; -} \ No newline at end of file +} diff --git a/tests/phpunit/tests/formatting/Smilies.php b/tests/phpunit/tests/formatting/Smilies.php index f1e69f7b27..e32aa535ef 100644 --- a/tests/phpunit/tests/formatting/Smilies.php +++ b/tests/phpunit/tests/formatting/Smilies.php @@ -16,15 +16,15 @@ class Tests_Formatting_Smilies extends WP_UnitTestCase { return array ( array ( 'Lorem ipsum dolor sit amet mauris ;-) Praesent gravida sodales. :lol: Vivamus nec diam in faucibus eu, bibendum varius nec, imperdiet purus est, at augue at lacus malesuada elit dapibus a, :eek: mauris. Cras mauris viverra elit. Nam laoreet viverra. Pellentesque tortor. Nam libero ante, porta urna ut turpis. Nullam wisi magna, :mrgreen: tincidunt nec, sagittis non, fringilla enim. Nam consectetuer nec, ullamcorper pede eu dui odio consequat vel, vehicula tortor quis pede turpis cursus quis, egestas ipsum ultricies ut, eleifend velit. Mauris vestibulum iaculis. Sed in nunc. Vivamus elit porttitor egestas. Mauris purus :?:', - 'Lorem ipsum dolor sit amet mauris ;-) Praesent gravida sodales. :lol: Vivamus nec diam in faucibus eu, bibendum varius nec, imperdiet purus est, at augue at lacus malesuada elit dapibus a, :eek: mauris. Cras mauris viverra elit. Nam laoreet viverra. Pellentesque tortor. Nam libero ante, porta urna ut turpis. Nullam wisi magna, :mrgreen: tincidunt nec, sagittis non, fringilla enim. Nam consectetuer nec, ullamcorper pede eu dui odio consequat vel, vehicula tortor quis pede turpis cursus quis, egestas ipsum ultricies ut, eleifend velit. Mauris vestibulum iaculis. Sed in nunc. Vivamus elit porttitor egestas. Mauris purus :?: ' + 'Lorem ipsum dolor sit amet mauris ;-) Praesent gravida sodales. :lol: Vivamus nec diam in faucibus eu, bibendum varius nec, imperdiet purus est, at augue at lacus malesuada elit dapibus a, :eek: mauris. Cras mauris viverra elit. Nam laoreet viverra. Pellentesque tortor. Nam libero ante, porta urna ut turpis. Nullam wisi magna, :mrgreen: tincidunt nec, sagittis non, fringilla enim. Nam consectetuer nec, ullamcorper pede eu dui odio consequat vel, vehicula tortor quis pede turpis cursus quis, egestas ipsum ultricies ut, eleifend velit. Mauris vestibulum iaculis. Sed in nunc. Vivamus elit porttitor egestas. Mauris purus :?:' ), array ( 'Welcome to the jungle! We got fun n games! :) We got everything you want 8-) Honey we know the names :)', - 'Welcome to the jungle! We got fun n games! :) We got everything you want 8-) Honey we know the names :) ' + 'Welcome to the jungle! We got fun n games! :) We got everything you want 8-) Honey we know the names :)' ), array ( "a little bit of this\na little bit:other: of that :D\n:D a little bit of good\nyeah with a little bit of bad8O", - "a little bit of this\na little bit:other: of that \":D\" \":D\" a little bit of good\nyeah with a little bit of bad8O" + "a little bit of this\na little bit:other: of that \":D\"\n\":D\" a little bit of good\nyeah with a little bit of bad8O" ), array ( 'and I say it\'s allright:D:D', @@ -48,8 +48,6 @@ class Tests_Formatting_Smilies extends WP_UnitTestCase { * when use_smilies = 1 and not when use_smilies = 0 */ function test_convert_standard_smilies( $in_txt, $converted_txt ) { - global $wpsmiliestrans; - // standard smilies, use_smilies: ON update_option( 'use_smilies', 1 ); @@ -61,8 +59,6 @@ class Tests_Formatting_Smilies extends WP_UnitTestCase { update_option( 'use_smilies', 0 ); $this->assertEquals( $in_txt, convert_smilies($in_txt) ); - - unset( $wpsmiliestrans ); } /** @@ -76,15 +72,15 @@ class Tests_Formatting_Smilies extends WP_UnitTestCase { return array ( array ( 'Peter Brian Gabriel (born 13 February 1950) is a British singer, musician, and songwriter who rose to fame as the lead vocalist and flautist of the progressive rock group Genesis. :monkey:', - 'Peter Brian Gabriel (born 13 February 1950) is a British singer, musician, and songwriter who rose to fame as the lead vocalist and flautist of the progressive rock group Genesis. :monkey: ' + 'Peter Brian Gabriel (born 13 February 1950) is a British singer, musician, and songwriter who rose to fame as the lead vocalist and flautist of the progressive rock group Genesis. :monkey:' ), array ( 'Star Wars Jedi Knight :arrow: Jedi Academy is a first and third-person shooter action game set in the Star Wars universe. It was developed by Raven Software and published, distributed and marketed by LucasArts in North America and by Activision in the rest of the world. :nervou:', - 'Star Wars Jedi Knight :arrow: Jedi Academy is a first and third-person shooter action game set in the Star Wars universe. It was developed by Raven Software and published, distributed and marketed by LucasArts in North America and by Activision in the rest of the world. :nervou: ' + 'Star Wars Jedi Knight :arrow: Jedi Academy is a first and third-person shooter action game set in the Star Wars universe. It was developed by Raven Software and published, distributed and marketed by LucasArts in North America and by Activision in the rest of the world. :nervou:' ), array ( ':arrow: monkey: Lorem ipsum dolor sit amet enim. Etiam ullam :PP
corper. Suspendisse a pellentesque dui, non felis. :arrow: :arrow', - ' :arrow: monkey: Lorem ipsum dolor sit amet enim. Etiam ullam :PP
corper. Suspendisse a pellentesque dui, non felis. :arrow: :arrow' + ':arrow: monkey: Lorem ipsum dolor sit amet enim. Etiam ullam :PP
corper. Suspendisse a pellentesque dui, non felis. :arrow: :arrow' ), ); } @@ -96,10 +92,16 @@ class Tests_Formatting_Smilies extends WP_UnitTestCase { */ function test_convert_custom_smilies ( $in_txt, $converted_txt ) { global $wpsmiliestrans; - $trans_orig = $wpsmiliestrans; // save original translations array // custom smilies, use_smilies: ON update_option( 'use_smilies', 1 ); + + if ( !isset( $wpsmiliestrans ) ) { + smilies_init(); + } + + $trans_orig = $wpsmiliestrans; // save original translations array + $wpsmiliestrans = array( ':PP' => 'icon_tongue.gif', ':arrow:' => 'icon_arrow.gif', @@ -142,13 +144,10 @@ class Tests_Formatting_Smilies extends WP_UnitTestCase { * @dataProvider get_smilies_ignore_tags */ public function test_ignore_smilies_in_tags( $element ) { - global $wpsmiliestrans; - $trans_orig = $wpsmiliestrans; // save original translations array - $includes_path = includes_url("images/smilies/"); $in_str = 'Do we ingore smilies ;-) in ' . $element . ' tags <' . $element . '>My Content Here :?: '; - $exp_str = 'Do we ingore smilies ;-) in ' . $element . ' tags <' . $element . '>My Content Here :?: '; + $exp_str = 'Do we ingore smilies ;-) in ' . $element . ' tags <' . $element . '>My Content Here :?: '; // standard smilies, use_smilies: ON update_option( 'use_smilies', 1 ); @@ -158,8 +157,6 @@ class Tests_Formatting_Smilies extends WP_UnitTestCase { // standard smilies, use_smilies: OFF update_option( 'use_smilies', 0 ); - - $wpsmiliestrans = $trans_orig; // reset original translations array } /** @@ -172,27 +169,27 @@ class Tests_Formatting_Smilies extends WP_UnitTestCase { return array ( array ( '8-O :-(', - ' 8-O :-( ' + '8-O :-(' ), array ( '8-) 8-O', - ' 8-) 8-O ' + '8-) 8-O' ), array ( '8-) 8O', - ' 8-) 8O ' + '8-) 8O' ), array ( '8-) :-(', - ' 8-) :-( ' + '8-) :-(' ), array ( '8-) :twisted:', - ' 8-) :twisted: ' + '8-) :twisted:' ), array ( '8O :twisted: :( :? :(', - ' 8O :twisted: :( :? :( ' + '8O :twisted: :( :? :(' ), ); } @@ -205,8 +202,6 @@ class Tests_Formatting_Smilies extends WP_UnitTestCase { * @dataProvider get_smilies_combinations */ public function test_smilies_combinations( $in_txt, $converted_txt ) { - global $wpsmiliestrans; - // custom smilies, use_smilies: ON update_option( 'use_smilies', 1 ); smilies_init(); @@ -233,11 +228,11 @@ class Tests_Formatting_Smilies extends WP_UnitTestCase { ), array ( '8O :) additional text here :)', - '8O :) additional text here :) ' + '8O :) additional text here :)' ), array ( ':) :) :) :)', - ' :) :) :) :) ' + ':) :) :) :)' ), ); } @@ -251,11 +246,16 @@ class Tests_Formatting_Smilies extends WP_UnitTestCase { */ public function test_single_smilies_in_wpsmiliestrans( $in_txt, $converted_txt ) { global $wpsmiliestrans; - $orig_trans = $wpsmiliestrans; // save original tranlations array // standard smilies, use_smilies: ON update_option( 'use_smilies', 1 ); + if ( !isset( $wpsmiliestrans ) ) { + smilies_init(); + } + + $orig_trans = $wpsmiliestrans; // save original tranlations array + $wpsmiliestrans = array ( ':)' => 'icon_smile.gif' ); @@ -271,4 +271,55 @@ class Tests_Formatting_Smilies extends WP_UnitTestCase { $wpsmiliestrans = $orig_trans; // reset original translations array } -} \ No newline at end of file + + /** + * Check that $wp_smiliessearch pattern will match smilies + * between spaces, but never capture those spaces. + * + * Further check that spaces aren't randomly deleted + * or added when replacing the text with an image. + * + * @ticket 22692 + */ + function test_spaces_around_smilies() { + $nbsp = "\xC2\xA0"; + + // standard smilies, use_smilies: ON + update_option( 'use_smilies', 1 ); + smilies_init(); + + $input = array(); + $output = array(); + + $input[] = 'My test :) smile'; + $output[] = array('test smile'); + + $input[] = 'My test ;) smile'; + $output[] = array('test smile'); + + $input[] = 'My test  :) smile'; + $output[] = array('test   smile'); + + $input[] = 'My test  ;) smile'; + $output[] = array('test   smile'); + + $input[] = "My test {$nbsp}:){$nbsp}smile"; + $output[] = array("test {$nbsp}{$nbsp}smile"); + + $input[] = "My test {$nbsp};){$nbsp}smile"; + $output[] = array("test {$nbsp}{$nbsp}smile"); + + foreach($input as $key => $in) { + $result = convert_smilies( $in ); + foreach($output[$key] as $out) { + + // Each output element must appear in the results. + $this->assertContains( $out, $result ); + + } + } + + // standard smilies, use_smilies: OFF + update_option( 'use_smilies', 0 ); + } +}