Make WordPress Core

Changeset 28727


Ignore:
Timestamp:
06/10/2014 02:33:16 PM (12 years ago)
Author:
wonderboymusic
Message:

In wptexturize(), ensure that texturization does not corrupt contents of HTML elements, HTML comments, and smartcode attributes.

Adds a variety of unit tests/assertions.

Props miqrogroove.
Fixes #12690, #8912, #27602.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/formatting.php

    r28726 r28727  
    159159        }
    160160
     161        // If there's nothing to do, just stop.
     162        if ( empty( $text ) ) {
     163                return $text;
     164        }
     165
    161166        // Transform into regexp sub-expression used in _wptexturize_pushpop_element
    162167        // Must do this every time in case plugins use these filters in a context sensitive manner
     
    181186        $no_texturize_shortcodes_stack = array();
    182187
    183         $textarr = preg_split('/(<.*>|\[.*\])/Us', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
     188        // Look for shortcodes and HTML elements.
     189
     190        $regex =  '/('                  // Capture the entire match.
     191                .       '<'             // Find start of element.
     192                .       '(?(?=!--)'     // Is this a comment?
     193                .               '.+?--\s*>'     // Find end of comment
     194                .       '|'
     195                .               '.+?>'          // Find end of element
     196                .       ')'
     197                . '|'
     198                .       '\['            // Find start of shortcode.
     199                .       '\[?'           // Shortcodes may begin with [[
     200                .       '[^\[\]<>]+'    // Shortcodes do not contain other shortcodes or HTML elements.
     201                .       '\]'            // Find end of shortcode.
     202                .       '\]?'           // Shortcodes may end with ]]
     203                . ')/s';
     204
     205        $textarr = preg_split( $regex, $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
    184206
    185207        foreach ( $textarr as &$curl ) {
    186                 if ( empty( $curl ) ) {
    187                         continue;
    188                 }
    189 
    190                 // Only call _wptexturize_pushpop_element if first char is correct tag opening
     208                // Only call _wptexturize_pushpop_element if $curl is a delimeter.
    191209                $first = $curl[0];
    192                 if ( '<' === $first ) {
    193                         _wptexturize_pushpop_element($curl, $no_texturize_tags_stack, $no_texturize_tags, '<', '>');
    194                 } elseif ( '[' === $first ) {
    195                         _wptexturize_pushpop_element($curl, $no_texturize_shortcodes_stack, $no_texturize_shortcodes, '[', ']');
     210                if ( '<' === $first && '>' === substr( $curl, -1 ) ) {
     211                        // This is an HTML delimeter.
     212
     213                        if ( '<!--' !== substr( $curl, 0, 4 ) ) {
     214                                _wptexturize_pushpop_element( $curl, $no_texturize_tags_stack, $no_texturize_tags, '<', '>' );
     215                        }
     216
     217                } elseif ( '[' === $first && 1 === preg_match( '/^\[[^\[\]<>]+\]$/', $curl ) ) {
     218                        // This is a shortcode delimeter.
     219
     220                        _wptexturize_pushpop_element( $curl, $no_texturize_shortcodes_stack, $no_texturize_shortcodes, '[', ']' );
     221
     222                } elseif ( '[' === $first && 1 === preg_match( '/^\[\[?[^\[\]<>]+\]\]?$/', $curl ) ) {
     223                        // This is an escaped shortcode delimeter.
     224
     225                        // Do not texturize.
     226                        // Do not push to the shortcodes stack.
     227
    196228                } elseif ( empty($no_texturize_shortcodes_stack) && empty($no_texturize_tags_stack) ) {
    197 
    198                         // This is not a tag, nor is the texturization disabled static strings
     229                        // This is neither a delimeter, nor is this content inside of no_texturize pairs.  Do texturize.
     230
    199231                        $curl = str_replace($static_characters, $static_replacements, $curl);
    200 
    201                         // regular expressions
    202232                        $curl = preg_replace($dynamic_characters, $dynamic_replacements, $curl);
    203233
  • trunk/tests/phpunit/tests/formatting/WPTexturize.php

    r28726 r28727  
    11291129                );
    11301130        }
     1131
     1132        /**
     1133         * Test HTML and shortcode avoidance.
     1134         *
     1135         * @ticket 12690
     1136         * @dataProvider data_tag_avoidance
     1137         */
     1138        function test_tag_avoidance( $input, $output ) {
     1139                return $this->assertEquals( $output, wptexturize( $input ) );
     1140        }
     1141
     1142        function data_tag_avoidance() {
     1143                return array(
     1144                        array(
     1145                                '[ photos by <a href="http://example.com/?a[]=1&a[]=2"> this guy </a> ]',
     1146                                '[ photos by <a href="http://example.com/?a[]=1&#038;a[]=2"> this guy </a> ]',
     1147                        ),
     1148                        array(
     1149                                '[gallery ...]',
     1150                                '[gallery ...]',
     1151                        ),
     1152                        array(
     1153                                '[[gallery ...]', // This tag is still valid.
     1154                                '[[gallery ...]',
     1155                        ),
     1156                        array(
     1157                                '[gallery ...]]', // This tag is also valid.
     1158                                '[gallery ...]]',
     1159                        ),
     1160                        array(
     1161                                '[/...]', // This would actually be ignored by the shortcode system.  The decision to not texturize it is intentional, if not correct.
     1162                                '[/...]',
     1163                        ),
     1164                        array(
     1165                                '[...]...[/...]', // These are potentially usable shortcodes.
     1166                                '[...]&#8230;[/...]',
     1167                        ),
     1168                        array(
     1169                                '[[...]]...[[/...]]', // Shortcode parsing will ignore the inner ]...[ part and treat this as a single escaped shortcode.
     1170                                '[[...]]&#8230;[[/...]]',
     1171                        ),
     1172                        array(
     1173                                '[[[...]]]...[[[/...]]]', // Again, shortcode parsing matches, but only the [[...] and [/...]] parts.
     1174                                '[[[...]]]&#8230;[[[/...]]]',
     1175                        ),
     1176                        array(
     1177                                '[[code]...[/code]...', // These are potentially usable shortcodes.  Unfortunately, the meaning of [[/code] is ambiguous unless we run the entire shortcode regexp.
     1178                                '[[code]&#8230;[/code]...', // Same behavior as 3.9 due to buggy logic in _wptexturize_pushpop_element().  See ticket #28483.
     1179                        ),
     1180                        array(
     1181                                '[code]...[/code]]...', // These are potentially usable shortcodes.  Unfortunately, the meaning of [/code]] is ambiguous unless we run the entire shortcode regexp.
     1182                                '[code]...[/code]]...', // This test would not pass in 3.9 because the extra brace was always ignored by texturize.
     1183                        ),
     1184                        array(
     1185                                '[gal>ery ...]',
     1186                                '[gal>ery &#8230;]',
     1187                        ),
     1188                        array(
     1189                                '[gallery ...',
     1190                                '[gallery &#8230;',
     1191                        ),
     1192                        array(
     1193                                '[gallery <br ... /> ...]',
     1194                                '[gallery <br ... /> &#8230;]',
     1195                        ),
     1196                        array(
     1197                                '<br [gallery ...] ... />',
     1198                                '<br [gallery ...] ... />',
     1199                        ),
     1200                        array(
     1201                                '<br [gallery ...] ... /',
     1202                                '<br [gallery ...] &#8230; /',
     1203                        ),
     1204                        array(
     1205                                '<br ... />',
     1206                                '<br ... />',
     1207                        ),
     1208                        array(
     1209                                '<br ... />...<br ... />',
     1210                                '<br ... />&#8230;<br ... />',
     1211                        ),
     1212                        array(
     1213                                '[gallery ...]...[gallery ...]',
     1214                                '[gallery ...]&#8230;[gallery ...]',
     1215                        ),
     1216                        array(
     1217                                '[[gallery ...]]',
     1218                                '[[gallery ...]]',
     1219                        ),
     1220                        array(
     1221                                '[[gallery ...]',
     1222                                '[[gallery ...]',
     1223                        ),
     1224                        array(
     1225                                '[gallery ...]]',
     1226                                '[gallery ...]]',
     1227                        ),
     1228                        array(
     1229                                '[/gallery ...]]',
     1230                                '[/gallery ...]]',
     1231                        ),
     1232                        array(
     1233                                '[[gallery <br ... /> ...]]',
     1234                                '[[gallery <br ... /> &#8230;]]',
     1235                        ),
     1236                        array(
     1237                                '<br [[gallery ...]] ... />',
     1238                                '<br [[gallery ...]] ... />',
     1239                        ),
     1240                        array(
     1241                                '<br [[gallery ...]] ... /',
     1242                                '<br [[gallery ...]] &#8230; /',
     1243                        ),
     1244                        array(
     1245                                '[[gallery ...]]...[[gallery ...]]',
     1246                                '[[gallery ...]]&#8230;[[gallery ...]]',
     1247                        ),
     1248                        array(
     1249                                '[[gallery ...]...[/gallery]]',
     1250                                '[[gallery ...]&#8230;[/gallery]]',
     1251                        ),
     1252                        array(
     1253                                '<!-- ... -->',
     1254                                '<!-- ... -->',
     1255                        ),
     1256                        array(
     1257                                '<!--...-->',
     1258                                '<!--...-->',
     1259                        ),
     1260                        array(
     1261                                '<!-- ... -- >',
     1262                                '<!-- ... -- >',
     1263                        ),
     1264                        array(
     1265                                '<!-- <br /> [gallery] ... -->',
     1266                                '<!-- <br /> [gallery] ... -->',
     1267                        ),
     1268                        array(
     1269                                '...<!-- ... -->...',
     1270                                '&#8230;<!-- ... -->&#8230;',
     1271                        ),
     1272                        array(
     1273                                '[gallery ...]...<!-- ... -->...<br ... />',
     1274                                '[gallery ...]&#8230;<!-- ... -->&#8230;<br ... />',
     1275                        ),
     1276                        array(
     1277                                '<ul><li>Hello.</li><!--<li>Goodbye.</li>--></ul>',
     1278                                '<ul><li>Hello.</li><!--<li>Goodbye.</li>--></ul>',
     1279                        ),
     1280                );
     1281        }
    11311282}
Note: See TracChangeset for help on using the changeset viewer.