diff --git a/src/wp-includes/js/shortcode.js b/src/wp-includes/js/shortcode.js index 34766fb651..7028f6a8bd 100644 --- a/src/wp-includes/js/shortcode.js +++ b/src/wp-includes/js/shortcode.js @@ -135,7 +135,7 @@ window.wp = window.wp || {}; // 6. an unquoted value. // 7. A numeric attribute in double quotes. // 8. An unquoted numeric attribute. - pattern = /(\w+)\s*=\s*"([^"]*)"(?:\s|$)|(\w+)\s*=\s*\'([^\']*)\'(?:\s|$)|(\w+)\s*=\s*([^\s\'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|(\S+)(?:\s|$)/g; + pattern = /([\w-]+)\s*=\s*"([^"]*)"(?:\s|$)|([\w-]+)\s*=\s*'([^']*)'(?:\s|$)|([\w-]+)\s*=\s*([^\s'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|(\S+)(?:\s|$)/g; // Map zero-width spaces to actual spaces. text = text.replace( /[\u00a0\u200b]/g, ' ' ); diff --git a/src/wp-includes/shortcodes.php b/src/wp-includes/shortcodes.php index 0042877e17..057fad73be 100644 --- a/src/wp-includes/shortcodes.php +++ b/src/wp-includes/shortcodes.php @@ -450,6 +450,17 @@ function unescape_invalid_shortcodes( $content ) { return $content; } +/** + * Retrieve the shortcode attributes regex. + * + * @since 4.4.0 + * + * @return string The shortcode attribute regular expression + */ +function get_shortcode_atts_regex() { + return '/([\w-]+)\s*=\s*"([^"]*)"(?:\s|$)|([\w-]+)\s*=\s*\'([^\']*)\'(?:\s|$)|([\w-]+)\s*=\s*([^\s\'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|(\S+)(?:\s|$)/'; +} + /** * Retrieve all attributes from the shortcodes tag. * @@ -467,7 +478,7 @@ function unescape_invalid_shortcodes( $content ) { */ function shortcode_parse_atts($text) { $atts = array(); - $pattern = '/([\w-]+)\s*=\s*"([^"]*)"(?:\s|$)|([\w-]+)\s*=\s*\'([^\']*)\'(?:\s|$)|([\w-]+)\s*=\s*([^\s\'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|(\S+)(?:\s|$)/'; + $pattern = get_shortcode_atts_regex(); $text = preg_replace("/[\x{00a0}\x{200b}]+/u", " ", $text); if ( preg_match_all($pattern, $text, $match, PREG_SET_ORDER) ) { foreach ($match as $m) { diff --git a/tests/phpunit/tests/shortcode.php b/tests/phpunit/tests/shortcode.php index 92beb4a8bd..a2ff424d4f 100644 --- a/tests/phpunit/tests/shortcode.php +++ b/tests/phpunit/tests/shortcode.php @@ -632,4 +632,18 @@ EOF; require_once( DIR_TESTDATA . '/formatting/whole-posts.php' ); return data_whole_posts(); } + + function test_php_and_js_shortcode_attribute_regexes_match() { + + $file = file_get_contents( ABSPATH . WPINC . '/js/shortcode.js' ); + $matched = preg_match( '|\s+pattern = (\/.+\/)g;|', $file, $matches ); + $php = get_shortcode_atts_regex(); + + $this->assertSame( 1, $matched ); + + $js = str_replace( "\'", "'", $matches[1] ); + $this->assertSame( $php, $js ); + + } + }