WordPress.org

Make WordPress Core

Ticket #2833: 2833.2.diff

File 2833.2.diff, 5.5 KB (added by cmmarslender, 6 years ago)

Fixes altering contents of <script> tags

  • src/wp-includes/formatting.php

     
    200200 * @return string Text which has been converted into correct paragraph tags.
    201201 */
    202202function wpautop($pee, $br = true) {
    203         $pre_tags = array();
    204 
    205203        if ( trim($pee) === '' )
    206204                return '';
    207205
    208206        $pee = $pee . "\n"; // just to make things a little easier, pad the end
    209207
    210         if ( strpos($pee, '<pre') !== false ) {
    211                 $pee_parts = explode( '</pre>', $pee );
    212                 $last_pee = array_pop($pee_parts);
    213                 $pee = '';
    214                 $i = 0;
     208        // Pull out pre tags and add placeholders
     209        $pre_result = _wpautop_add_tag_placeholders( $pee, 'pre' );
     210        $pee = $pre_result['pee'];
     211        $pre_tags = $pre_result['tags'];
     212        unset( $pre_result );
    215213
    216                 foreach ( $pee_parts as $pee_part ) {
    217                         $start = strpos($pee_part, '<pre');
     214        // Pull out script tags and add placeholders
     215        $script_result = _wpautop_add_tag_placeholders( $pee, 'script' );
     216        $pee = $script_result['pee'];
     217        $script_tags = $script_result['tags'];
     218        unset( $script_result );
    218219
    219                         // Malformed html?
    220                         if ( $start === false ) {
    221                                 $pee .= $pee_part;
    222                                 continue;
    223                         }
    224 
    225                         $name = "<pre wp-pre-tag-$i></pre>";
    226                         $pre_tags[$name] = substr( $pee_part, $start ) . '</pre>';
    227 
    228                         $pee .= substr( $pee_part, 0, $start ) . $name;
    229                         $i++;
    230                 }
    231 
    232                 $pee .= $last_pee;
    233         }
    234 
    235220        $pee = preg_replace('|<br />\s*<br />|', "\n\n", $pee);
    236221        // Space things out a little
    237222        $allblocks = '(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|form|map|area|blockquote|address|math|style|p|h[1-6]|hr|fieldset|noscript|legend|section|article|aside|hgroup|header|footer|nav|figure|details|menu|summary)';
     
    281266        $pee = preg_replace('!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $pee);
    282267        $pee = preg_replace( "|\n</p>$|", '</p>', $pee );
    283268
    284         if ( !empty($pre_tags) )
    285                 $pee = str_replace(array_keys($pre_tags), array_values($pre_tags), $pee);
     269        $pee = _wpautop_replace_tag_placeholders( $pee, $pre_tags );
     270        $pee = _wpautop_replace_tag_placeholders( $pee, $script_tags );
    286271
    287272        return $pee;
    288273}
    289274
    290275/**
     276 * Searches the provided text for the specified tags and adds placeholders in their place.
     277 *
     278 * Example: If 'pre' is provided as tag, anything between <pre> and </pre>, including the tags themselves would be
     279 * replaced with a placeholder. The placeholder and the original value will then be added to the $tags array.
     280 *
     281 * The function returns an array with two keys, 'pee' and 'tags'. 'pee' contains the original $pee text, except with
     282 * placeholders in place of the tags. 'tags' is an array where the array key is the placeholder and the array value is
     283 * what was replaced by the placeholder.
     284 *
     285 * @param string $pee The text which has to be formatted.
     286 * @param string $tag The tag to replace with placeholders.
     287 *
     288 * @return array Returns an array containing 'pee' and 'tags'
     289 */
     290function _wpautop_add_tag_placeholders( $pee, $tag ) {
     291        $tags = array();
     292
     293        if ( false !== strpos( $pee, "<{$tag}" ) ) {
     294                $pee_parts = explode( "</{$tag}>", $pee );
     295                $last_pee = array_pop( $pee_parts );
     296                $pee = '';
     297                $i = 0;
     298
     299                foreach ( $pee_parts as $pee_part ) {
     300                        $start = strpos( $pee_part, "<{$tag}" );
     301
     302                        // Malformed html?
     303                        if ( false === $start ) {
     304                                $pee .= $pee_part;
     305                                continue;
     306                        }
     307
     308                        $name = "<{$tag} wp-{$tag}-tag-$i></{$tag}>";
     309                        $tags[ $name ] = substr( $pee_part, $start ) . "</{$tag}>";
     310
     311                        $pee .= substr( $pee_part, 0, $start ) . $name;
     312                        $i++;
     313                }
     314
     315                $pee .= $last_pee;
     316        }
     317
     318        return array( 'pee' => $pee, 'tags' => $tags );
     319}
     320
     321/**
     322 * Replaces placeholders in $pee with their original values as specified in $tags.
     323 *
     324 * Designed to be used with _wpautop_add_tag_placeholders, this function replaces text in $pee by replacing each of the
     325 * array keys in $tags with the corresponding array values.
     326 *
     327 * @param string $pee The text which has to be formatted.
     328 * @param array $tags Values to search for and replace.
     329 *
     330 * @return string Text which has had all the placeholders specified in tags replaced with their original values.
     331 */
     332function _wpautop_replace_tag_placeholders( $pee, $tags ) {
     333        if ( ! empty( $tags ) ) {
     334                $pee = str_replace( array_keys( $tags ), array_values( $tags ), $pee );
     335        }
     336
     337        return $pee;
     338}
     339
     340/**
    291341 * Newline preservation help function for wpautop
    292342 *
    293343 * @since 3.1.0
  • tests/phpunit/tests/formatting/Autop.php

     
    9090        }
    9191
    9292        /**
     93         * wpautop() Should not alter the contents of "<script>" elements
     94         *
     95         * @ticket 2833
     96         */
     97        public function test_skip_script_elements() {
     98                $code = file_get_contents( DIR_TESTDATA . '/formatting/sizzle.js' );
     99                $code = str_replace( "\r", '', $code );
     100                $code = htmlentities( $code );
     101
     102                // Not wrapped in <p> tags
     103                $str = "<p><script>$code</script></p>";
     104                $this->assertEquals( $str, trim( wpautop( $str ) ) );
     105
     106                // Text before/after is wrapped in <p> tags
     107                $str = "Look at this code\n\n<script>$code</script>\n\nIsn't that cool?";
     108
     109                // Expected text after wpautop
     110                $expected = '<p>Look at this code</p>' . "\n<p><script>" . $code . "</script></p>\n" . '<p>Isn\'t that cool?</p>';
     111                $this->assertEquals( $expected, trim( wpautop( $str ) ) );
     112        }
     113
     114        /**
    93115         * wpautop() Should not add <br/> to "<input>" elements
    94116         *
    95117         * @ticket 16456