Ticket #47014: 47014.diff
| File 47014.diff, 8.9 KB (added by , 7 years ago) |
|---|
-
src/wp-includes/formatting.php
2465 2465 // WP bug fix for LOVE <3 (and other situations with '<' before a number) 2466 2466 $text = preg_replace( '#<([0-9]{1})#', '<$1', $text ); 2467 2467 2468 while ( preg_match( '/<(\/?[ \w:]*)\s*([^>]*)>/', $text, $regex ) ) {2468 while ( preg_match( '/<(\/?[a-z0-9]+-[a-z0-9-]+|\/?[\w:]*)(\s*)([^>]*)>/', $text, $regex ) ) { 2469 2469 $newtext .= $tagqueue; 2470 2470 2471 2471 $i = strpos( $text, $regex[0] ); 2472 2472 $l = strlen( $regex[0] ); 2473 2473 2474 // Do not modify since tags shouldn't end in a dash. 2475 if ( empty( $regex[2] ) && isset( $regex[3][0] ) && '-' === $regex[3][0] ) { 2476 $newtext .= substr( $text, 0, $i + $l ); 2477 $text = substr( $text, $i + $l ); 2478 continue; 2479 } 2480 2474 2481 // clear the shifter 2475 2482 $tagqueue = ''; 2476 2483 // Pop or Push … … 2508 2515 // If it's an empty tag "< >", do nothing 2509 2516 if ( '' == $tag ) { 2510 2517 // do nothing 2511 } elseif ( substr( $regex[ 2], -1 ) == '/' ) { // ElseIf it presents itself as a self-closing tag...2518 } elseif ( substr( $regex[3], -1 ) == '/' ) { // ElseIf it presents itself as a self-closing tag... 2512 2519 // ...but it isn't a known single-entity self-closing tag, then don't let it be treated as such and 2513 2520 // immediately close it with a closing tag (the tag will encapsulate no text as a result) 2514 2521 if ( ! in_array( $tag, $single_tags ) ) { 2515 $regex[ 2] = trim( substr( $regex[2], 0, -1 ) ) . "></$tag";2522 $regex[3] = trim( substr( $regex[3], 0, -1 ) ) . "></$tag"; 2516 2523 } 2517 2524 } elseif ( in_array( $tag, $single_tags ) ) { // ElseIf it's a known single-entity tag but it doesn't close itself, do so 2518 $regex[ 2] .= '/';2525 $regex[3] .= '/'; 2519 2526 } else { // Else it's not a single-entity tag 2520 2527 // If the top of the stack is the same as the tag we want to push, close previous tag 2521 2528 if ( $stacksize > 0 && ! in_array( $tag, $nestable_tags ) && $tagstack[ $stacksize - 1 ] == $tag ) { … … 2526 2533 } 2527 2534 2528 2535 // Attributes 2529 $attributes = $regex[ 2];2536 $attributes = $regex[3]; 2530 2537 if ( ! empty( $attributes ) && $attributes[0] != '>' ) { 2531 2538 $attributes = ' ' . $attributes; 2532 2539 } … … 3040 3047 function wp_targeted_link_rel( $text ) { 3041 3048 // Don't run (more expensive) regex if no links with targets. 3042 3049 if ( stripos( $text, 'target' ) !== false && stripos( $text, '<a ' ) !== false ) { 3043 if ( ! is_serialized( $text ) ) { 3044 $text = preg_replace_callback( '|<a\s([^>]*target\s*=[^>]*)>|i', 'wp_targeted_link_rel_callback', $text ); 3045 } 3050 $text = preg_replace_callback( '|<a\s([^>]*target\s*=[^>]*)>|i', 'wp_targeted_link_rel_callback', $text ); 3046 3051 } 3047 3052 3048 3053 return $text; … … 3096 3101 $delimiter = trim( $rel_match[1] ) ? $rel_match[1] : '"'; 3097 3102 $rel = 'rel=' . $delimiter . trim( implode( ' ', $parts ) ) . $delimiter; 3098 3103 $link_html = str_replace( $rel_match[0], $rel, $link_html ); 3099 } elseif ( preg_match( '|target\s*=\s*?\\\\"|', $link_html ) ) {3100 $link_html .= " rel=\\\"$rel\\\"";3101 } elseif ( preg_match( '#(target|href)\s*=\s*?\'#', $link_html ) ) {3102 $link_html .= " rel='$rel'";3103 3104 } else { 3104 3105 $link_html .= " rel=\"$rel\""; 3105 3106 } … … 3432 3433 if ( $tz ) { 3433 3434 $datetime = date_create( $string, new DateTimeZone( 'UTC' ) ); 3434 3435 if ( ! $datetime ) { 3435 return gmdate( $format, 0 );3436 return date( $format, 0 ); 3436 3437 } 3437 3438 $datetime->setTimezone( new DateTimeZone( $tz ) ); 3438 3439 $string_localtime = $datetime->format( $format ); 3439 3440 } else { 3440 3441 if ( ! preg_match( '#([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})#', $string, $matches ) ) { 3441 return gmdate( $format, 0 );3442 return date( $format, 0 ); 3442 3443 } 3443 3444 $string_time = gmmktime( $matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1] ); 3444 3445 $string_localtime = gmdate( $format, $string_time + get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ); … … 4811 4812 * @since 2.5.0 4812 4813 * @link https://secure.php.net/sprintf 4813 4814 * 4814 * @param string $pattern The string which formatted args are inserted.4815 * @param mixed ...$argsArguments to be formatted into the $pattern string.4815 * @param string $pattern The string which formatted args are inserted. 4816 * @param mixed $args ,... Arguments to be formatted into the $pattern string. 4816 4817 * @return string The formatted string. 4817 4818 */ 4818 4819 function wp_sprintf( $pattern ) { … … 5520 5521 5521 5522 /* 5522 5523 * If you're looking at a src version of this file, you'll see an "include" 5523 * statement below. This is used by the ` npm runbuild` process to directly5524 * statement below. This is used by the `grunt build` process to directly 5524 5525 * include a minified version of wp-emoji-loader.js, instead of using the 5525 5526 * readfile() method from above. 5526 5527 * … … 5531 5532 ?> 5532 5533 <script type="text/javascript"> 5533 5534 window._wpemojiSettings = <?php echo wp_json_encode( $settings ); ?>; 5534 include "js/wp-emoji-loader.min.js"5535 !function(a,b,c){function d(a,b){var c=String.fromCharCode;l.clearRect(0,0,k.width,k.height),l.fillText(c.apply(this,a),0,0);var d=k.toDataURL();l.clearRect(0,0,k.width,k.height),l.fillText(c.apply(this,b),0,0);var e=k.toDataURL();return d===e}function e(a){var b;if(!l||!l.fillText)return!1;switch(l.textBaseline="top",l.font="600 32px Arial",a){case"flag":return!(b=d([55356,56826,55356,56819],[55356,56826,8203,55356,56819]))&&(b=d([55356,57332,56128,56423,56128,56418,56128,56421,56128,56430,56128,56423,56128,56447],[55356,57332,8203,56128,56423,8203,56128,56418,8203,56128,56421,8203,56128,56430,8203,56128,56423,8203,56128,56447]),!b);case"emoji":return b=d([55357,56424,55356,57342,8205,55358,56605,8205,55357,56424,55356,57340],[55357,56424,55356,57342,8203,55358,56605,8203,55357,56424,55356,57340]),!b}return!1}function f(a){var c=b.createElement("script");c.src=a,c.defer=c.type="text/javascript",b.getElementsByTagName("head")[0].appendChild(c)}var g,h,i,j,k=b.createElement("canvas"),l=k.getContext&&k.getContext("2d");for(j=Array("flag","emoji"),c.supports={everything:!0,everythingExceptFlag:!0},i=0;i<j.length;i++)c.supports[j[i]]=e(j[i]),c.supports.everything=c.supports.everything&&c.supports[j[i]],"flag"!==j[i]&&(c.supports.everythingExceptFlag=c.supports.everythingExceptFlag&&c.supports[j[i]]);c.supports.everythingExceptFlag=c.supports.everythingExceptFlag&&!c.supports.flag,c.DOMReady=!1,c.readyCallback=function(){c.DOMReady=!0},c.supports.everything||(h=function(){c.readyCallback()},b.addEventListener?(b.addEventListener("DOMContentLoaded",h,!1),a.addEventListener("load",h,!1)):(a.attachEvent("onload",h),b.attachEvent("onreadystatechange",function(){"complete"===b.readyState&&c.readyCallback()})),g=c.source||{},g.concatemoji?f(g.concatemoji):g.wpemoji&&g.twemoji&&(f(g.twemoji),f(g.wpemoji)))}(window,document,window._wpemojiSettings); 5535 5536 </script> 5536 5537 <?php 5537 5538 } … … 5736 5737 * Returns arrays of emoji data. 5737 5738 * 5738 5739 * These arrays are automatically built from the regex in twemoji.js - if they need to be updated, 5739 * you should update the regex there, then run the ` npm rungrunt precommit:emoji` job.5740 * you should update the regex there, then run the `grunt precommit:emoji` job. 5740 5741 * 5741 5742 * @since 4.9.0 5742 5743 * @access private -
tests/phpunit/tests/formatting/balanceTags.php
68 68 '<em />', 69 69 '<p class="main1"/>', 70 70 '<p class="main2" />', 71 '<STRONG/>', 71 72 ); 72 73 $expected = array( 73 74 '<strong></strong>', … … 74 75 '<em></em>', 75 76 '<p class="main1"></p>', 76 77 '<p class="main2"></p>', 78 // Valid tags are transformed to lowercase. 79 '<strong></strong>', 77 80 ); 78 81 79 82 foreach ( $inputs as $key => $input ) { … … 221 224 } 222 225 } 223 226 227 /** 228 * Get custom element data. 229 * 230 * @return array Data. 231 */ 232 public function data_custom_elements() { 233 return array( 234 // Valid custom element tags. 235 array( 236 '<my-custom-element>Test</my-custom-element>', 237 '<my-custom-element>Test</my-custom-element>', 238 ), 239 array( 240 '<my-custom-element>Test', 241 '<my-custom-element>Test</my-custom-element>', 242 ), 243 array( 244 'Test</my-custom-element>', 245 'Test', 246 ), 247 array( 248 '</my-custom-element>Test', 249 'Test', 250 ), 251 // Invalid (or at least temporarily unsupported) custom element tags. 252 array( 253 '<MY-CUSTOM-ELEMENT>Test', 254 '<MY-CUSTOM-ELEMENT>Test', 255 ), 256 array( 257 '<my->Test', 258 '<my->Test', 259 ), 260 array( 261 '<--->Test', 262 '<--->Test', 263 ), 264 ); 265 } 266 267 /** 268 * Test custom elements. 269 * 270 * @ticket 47014 271 * @dataProvider data_custom_elements 272 * 273 * @param string $source Source. 274 * @param string $expected Expected. 275 */ 276 public function test_custom_elements( $source, $expected ) { 277 $this->assertEquals( $expected, balanceTags( $source, true ) ); 278 } 224 279 }