WordPress.org

Make WordPress Core

Ticket #22692: miqro-22692.14.patch

File miqro-22692.14.patch, 33.0 KB (added by miqrogroove, 7 years ago)
  • src/wp-includes/formatting.php

     
    7373                $static_characters = array_merge( array( '---', ' -- ', '--', ' - ', 'xn–', '...', '``', '\'\'', ' (tm)' ), $cockney );
    7474                $static_replacements = array_merge( array( $em_dash, ' ' . $em_dash . ' ', $en_dash, ' ' . $en_dash . ' ', 'xn--', '…', $opening_quote, $closing_quote, ' ™' ), $cockneyreplace );
    7575
     76                // Pattern-based replacements of characters.
    7677                $dynamic = array();
    77                 if ( "'" != $apos ) {
    78                         $dynamic[ '/\'(\d\d(?:’|\')?s)/' ] = $apos . '$1'; // '99's
    79                         $dynamic[ '/\'(\d)/'                   ] = $apos . '$1'; // '99
    80                 }
     78                $spaces = wp_spaces_regexp();
     79
     80                // '99s (apostrophe)
     81                if ( "'" != $apos )
     82                        $dynamic[ '/\'(?=\d)/' ] = $apos;
     83
     84                // Single quote at start, or preceded by (, {, <, [, ", or spaces.
    8185                if ( "'" != $opening_single_quote )
    82                         $dynamic[ '/(\s|\A|[([{<]|")\'/'       ] = '$1' . $opening_single_quote; // opening single quote, even after (, {, <, [
     86                        $dynamic[ '/(?<=\A|[([{<"]|' . $spaces . ')\'/' ] = $opening_single_quote;
     87
     88                // 9" (double prime)
    8389                if ( '"' != $double_prime )
    84                         $dynamic[ '/(\d)"/'                    ] = '$1' . $double_prime; // 9" (double prime)
     90                        $dynamic[ '/(?<=\d)"/' ] = $double_prime;
     91
     92                // 9' (prime)
    8593                if ( "'" != $prime )
    86                         $dynamic[ '/(\d)\'/'                   ] = '$1' . $prime; // 9' (prime)
     94                        $dynamic[ '/(?<=\d)\'/' ] = $prime;
     95
     96                // Apostrophe in a word.  No spaces or double primes.
    8797                if ( "'" != $apos )
    88                         $dynamic[ '/(\S)\'([^\'\s])/'          ] = '$1' . $apos . '$2'; // apostrophe in a word
     98                        $dynamic[ '/(?<!' . $spaces . ')\'(?!\'|' . $spaces . ')/' ] = $apos;
     99
     100                // Double quote at start, or preceded by (, {, <, [, or spaces, and not followed by spaces.
    89101                if ( '"' != $opening_quote )
    90                         $dynamic[ '/(\s|\A|[([{<])"(?!\s)/'    ] = '$1' . $opening_quote . '$2'; // opening double quote, even after (, {, <, [
     102                        $dynamic[ '/(?<=\A|[([{<]|' . $spaces . ')"(?!' . $spaces . ')/' ] = $opening_quote;
     103
     104                // Any remaining double quotes.
    91105                if ( '"' != $closing_quote )
    92                         $dynamic[ '/"(\s|\S|\Z)/'              ] = $closing_quote . '$1'; // closing double quote
     106                        $dynamic[ '/"/' ] = $closing_quote;
     107
     108                // Single quotes followed by spaces or a period.
    93109                if ( "'" != $closing_single_quote )
    94                         $dynamic[ '/\'([\s.]|\Z)/'             ] = $closing_single_quote . '$1'; // closing single quote
     110                        $dynamic[ '/\'(?=\Z|\.|' . $spaces . ')/' ] = $closing_single_quote;
    95111
    96                 $dynamic[ '/\b(\d+)x(\d+)\b/'              ] = '$1&#215;$2'; // 9x9 (times)
    97 
    98112                $dynamic_characters = array_keys( $dynamic );
    99113                $dynamic_replacements = array_values( $dynamic );
    100114        }
     
    134148                } elseif ( '[' === $first ) {
    135149                        _wptexturize_pushpop_element($curl, $no_texturize_shortcodes_stack, $no_texturize_shortcodes, '[', ']');
    136150                } elseif ( empty($no_texturize_shortcodes_stack) && empty($no_texturize_tags_stack) ) {
     151
    137152                        // This is not a tag, nor is the texturization disabled static strings
    138153                        $curl = str_replace($static_characters, $static_replacements, $curl);
     154
    139155                        // regular expressions
    140156                        $curl = preg_replace($dynamic_characters, $dynamic_replacements, $curl);
     157
     158                        // 9x9 (times)
     159                        if ( 1 === preg_match( '/(?<=\d)x\d/', $text ) ) {
     160
     161                                // Searching for a digit is 10 times more expensive than for the x, so we avoid doing this one!
     162                                $curl = preg_replace('/\b(\d+)x(\d+)\b/', '$1&#215;$2', $curl);
     163
     164                        }
    141165                }
     166
     167                // Replace each & with &#038; unless it already looks like an entity.
    142168                $curl = preg_replace('/&([^#])(?![a-zA-Z1-4]{1,8};)/', '&#038;$1', $curl);
    143169        }
    144170        return implode( '', $textarr );
     
    318344        }
    319345
    320346        $tagregexp = join( '|', array_map( 'preg_quote', array_keys( $shortcode_tags ) ) );
     347        $spaces = wp_spaces_regexp();
    321348
    322349        $pattern =
    323350                  '/'
    324351                . '<p>'                              // Opening paragraph
    325                 . '\\s*+'                            // Optional leading whitespace
     352                . '(?:' . $spaces . ')*+'            // Optional leading whitespace
    326353                . '('                                // 1: The shortcode
    327354                .     '\\['                          // Opening bracket
    328355                .     "($tagregexp)"                 // 2: Shortcode name
     
    347374                .         ')?'
    348375                .     ')'
    349376                . ')'
    350                 . '\\s*+'                            // optional trailing whitespace
     377                . '(?:' . $spaces . ')*+'            // optional trailing whitespace
    351378                . '<\\/p>'                           // closing paragraph
    352379                . '/s';
    353380
     
    18651892         */
    18661893        $src_url = apply_filters( 'smilies_src', includes_url( "images/smilies/$img" ), $img, site_url() );
    18671894
    1868         return sprintf( ' <img src="%s" alt="%s" class="wp-smiley" /> ', esc_url( $src_url ), esc_attr( $smiley ) );
     1895        return sprintf( '<img src="%s" alt="%s" class="wp-smiley" />', esc_url( $src_url ), esc_attr( $smiley ) );
    18691896}
    18701897
    18711898/**
     
    37813808
    37823809        return false;
    37833810}
     3811
     3812/**
     3813 * Returns the regexp for common whitespace characters.
     3814 *
     3815 * By default, spaces include new lines, tabs, nbsp entities, and the UTF-8 nbsp.
     3816 * This is designed to replace the PCRE \s sequence.  In ticket #22692, that
     3817 * sequence was found to be unreliable due to random inclusion of the A0 byte.
     3818 *
     3819 * @since 3.9.0
     3820 *
     3821 * @return string The spaces regexp.
     3822 */
     3823function wp_spaces_regexp() {
     3824        static $spaces;
     3825
     3826        if (empty($spaces)) {
     3827                $spaces = apply_filters( 'wp_spaces_regexp', '[\r\n\t ]|\xC2\xA0|&nbsp;' );
     3828        }
     3829
     3830        return $spaces;
     3831}
  • src/wp-includes/functions.php

     
    25602560         */
    25612561        krsort($wpsmiliestrans);
    25622562
    2563         $wp_smiliessearch = '/((?:\s|^)';
     2563        $spaces = wp_spaces_regexp();
    25642564
     2565        // Begin first "subpattern"
     2566        $wp_smiliessearch = '/(?<=' . $spaces . '|^)';
     2567
    25652568        $subchar = '';
    25662569        foreach ( (array) $wpsmiliestrans as $smiley => $img ) {
    25672570                $firstchar = substr($smiley, 0, 1);
     
    25702573                // new subpattern?
    25712574                if ($firstchar != $subchar) {
    25722575                        if ($subchar != '') {
    2573                                 $wp_smiliessearch .= ')(?=\s|$))|((?:\s|^)'; ;
     2576                                $wp_smiliessearch .= ')(?=' . $spaces . '|$)';  // End previous "subpattern"
     2577                                $wp_smiliessearch .= '|(?<=' . $spaces . '|^)'; // Begin another "subpattern"
    25742578                        }
    25752579                        $subchar = $firstchar;
    25762580                        $wp_smiliessearch .= preg_quote($firstchar, '/') . '(?:';
     
    25802584                $wp_smiliessearch .= preg_quote($rest, '/');
    25812585        }
    25822586
    2583         $wp_smiliessearch .= ')(?=\s|$))/m';
     2587        $wp_smiliessearch .= ')(?=' . $spaces . '|$)/m';
    25842588
    25852589}
    25862590
  • tests/phpunit/tests/formatting/Smilies.php

     
    275275
    276276                $wpsmiliestrans = $orig_trans; // reset original translations array
    277277        }
    278 }
    279  No newline at end of file
     278
     279        /**
     280         * Check that $wp_smiliessearch pattern will match smilies
     281         * between spaces, but never capture those spaces.
     282         *
     283         * Further check that spaces aren't randomly deleted
     284         * or added when replacing the text with an image.
     285         *
     286         * @ticket 22692
     287         */
     288        function test_spaces_around_smilies() {
     289                $nbsp = "\xC2\xA0";
     290
     291                $input  = array();
     292                $output = array();
     293
     294                $input[]  = 'My test :) smile';
     295                $output[] = array('test <img ', 'alt=":)"', ' /> smile');
     296
     297                $input[]  = 'My test ;) smile';
     298                $output[] = array('test <img ', 'alt=";)"', ' /> smile');
     299
     300                $input[]  = 'My test &nbsp;:)&nbsp;smile';
     301                $output[] = array('test &nbsp;<img ', 'alt=":)"', ' />&nbsp;smile');
     302
     303                $input[]  = 'My test &nbsp;;)&nbsp;smile';
     304                $output[] = array('test &nbsp;<img ', 'alt=";)"', ' />&nbsp;smile');
     305
     306                $input[]  = "My test {$nbsp}:){$nbsp}smile";
     307                $output[] = array("test {$nbsp}<img ", 'alt=":)"', " />{$nbsp}smile");
     308
     309                $input[]  = "My test {$nbsp};){$nbsp}smile";
     310                $output[] = array("test {$nbsp}<img ", 'alt=";)"', " />{$nbsp}smile");
     311
     312                foreach($input as $key => $in) {
     313                        $result = convert_smilies( $in );
     314                        foreach($output[$key] as $out) {
     315
     316                                // Each output element must appear in the results.
     317                                $this->assertContains( $out, $result );
     318
     319                        }
     320                }
     321        }
     322}
  • tests/phpunit/tests/formatting/WPTexturize.php

     
    1414                $this->assertEquals('[a]a&#8211;b[code]---[/code]a&#8211;b[/a]', wptexturize('[a]a--b[code]---[/code]a--b[/a]'));
    1515                $this->assertEquals('<pre><code></code>--</pre>', wptexturize('<pre><code></code>--</pre>'));
    1616
    17                 $this->assertEquals('<code>---</code>', wptexturize('<code>---</code>'));
     17                $this->assertEquals( '<code>---</code>',     wptexturize( '<code>---</code>'     ) );
     18                $this->assertEquals( '<kbd>---</kbd>',       wptexturize( '<kbd>---</kbd>'       ) );
     19                $this->assertEquals( '<style>---</style>',   wptexturize( '<style>---</style>'   ) );
     20                $this->assertEquals( '<script>---</script>', wptexturize( '<script>---</script>' ) );
     21                $this->assertEquals( '<tt>---</tt>',         wptexturize( '<tt>---</tt>'         ) );
    1822
    1923                $this->assertEquals('<code>href="baba"</code> &#8220;baba&#8221;', wptexturize('<code>href="baba"</code> "baba"'));
    2024
     
    4448        //WP Ticket #4539
    4549        function test_basic_quotes() {
    4650                $this->assertEquals('test&#8217;s', wptexturize('test\'s'));
    47                 $this->assertEquals('test&#8217;s', wptexturize('test\'s'));
    4851
    4952                $this->assertEquals('&#8216;quoted&#8217;', wptexturize('\'quoted\''));
    5053                $this->assertEquals('&#8220;quoted&#8221;', wptexturize('"quoted"'));
     
    184187         * @ticket 23185
    185188         */
    186189        function test_spaces_around_hyphens() {
     190                $nbsp = "\xC2\xA0";
     191
    187192                $this->assertEquals( ' &#8211; ', wptexturize( ' - ' ) );
    188193                $this->assertEquals( '&nbsp;&#8211;&nbsp;', wptexturize( '&nbsp;-&nbsp;' ) );
    189194                $this->assertEquals( ' &#8211;&nbsp;', wptexturize( ' -&nbsp;' ) );
    190195                $this->assertEquals( '&nbsp;&#8211; ', wptexturize( '&nbsp;- ') );
     196                $this->assertEquals( "$nbsp&#8211;$nbsp", wptexturize( "$nbsp-$nbsp" ) );
     197                $this->assertEquals( " &#8211;$nbsp", wptexturize( " -$nbsp" ) );
     198                $this->assertEquals( "$nbsp&#8211; ", wptexturize( "$nbsp- ") );
    191199
    192200                $this->assertEquals( ' &#8212; ', wptexturize( ' -- ' ) );
    193201                $this->assertEquals( '&nbsp;&#8212;&nbsp;', wptexturize( '&nbsp;--&nbsp;' ) );
    194202                $this->assertEquals( ' &#8212;&nbsp;', wptexturize( ' --&nbsp;' ) );
    195203                $this->assertEquals( '&nbsp;&#8212; ', wptexturize( '&nbsp;-- ') );
     204                $this->assertEquals( "$nbsp&#8212;$nbsp", wptexturize( "$nbsp--$nbsp" ) );
     205                $this->assertEquals( " &#8212;$nbsp", wptexturize( " --$nbsp" ) );
     206                $this->assertEquals( "$nbsp&#8212; ", wptexturize( "$nbsp-- ") );
    196207        }
     208
     209        /**
     210         * @ticket 22692
     211         */
     212        function test_spaces_around_quotes() {
     213                $nbsp = "\xC2\xA0";
     214                $pi   = "\xCE\xA0";
     215
     216                // This should never happen, even if the desired output changes some day.
     217
     218                $problem_input  = "$nbsp\"A";
     219                $problem_output = "$nbsp&#8221;A";
     220
     221                $this->assertNotEquals( $problem_output, wptexturize( $problem_input ) );
     222
     223                // These are desirable outputs for the current design.
     224
     225                $input  = array();
     226                $output = array();
     227
     228                $input[]  = "stop. $nbsp\"A quote after 2 spaces.\"";
     229                $output[] = "stop. $nbsp&#8220;A quote after 2 spaces.&#8221;";
     230
     231                $input[]  = "stop.$nbsp$nbsp\"A quote after 2 spaces.\"";
     232                $output[] = "stop.$nbsp$nbsp&#8220;A quote after 2 spaces.&#8221;";
     233
     234                $input[]  = "stop. $nbsp'A quote after 2 spaces.'";
     235                $output[] = "stop. $nbsp&#8216;A quote after 2 spaces.&#8217;";
     236
     237                $input[]  = "stop.$nbsp$nbsp'A quote after 2 spaces.'";
     238                $output[] = "stop.$nbsp$nbsp&#8216;A quote after 2 spaces.&#8217;";
     239
     240                $input[]  = "stop. &nbsp;\"A quote after 2 spaces.\"";
     241                $output[] = "stop. &nbsp;&#8220;A quote after 2 spaces.&#8221;";
     242
     243                $input[]  = "stop.&nbsp;&nbsp;\"A quote after 2 spaces.\"";
     244                $output[] = "stop.&nbsp;&nbsp;&#8220;A quote after 2 spaces.&#8221;";
     245
     246                $input[]  = "stop. &nbsp;'A quote after 2 spaces.'";
     247                $output[] = "stop. &nbsp;&#8216;A quote after 2 spaces.&#8217;";
     248
     249                $input[]  = "stop.&nbsp;&nbsp;'A quote after 2 spaces.'";
     250                $output[] = "stop.&nbsp;&nbsp;&#8216;A quote after 2 spaces.&#8217;";
     251
     252                $input[]  = "Contraction: $pi's";
     253                $output[] = "Contraction: $pi&#8217;s";
     254
     255                foreach($input as $key => $in) {
     256                        $this->assertEquals( $output[$key], wptexturize( $in ) );
     257                }
     258        }
     259
     260        /**
     261         * Check all baseline patterns.  If anything ever changes in wptexturize(), these tests may fail.
     262         *
     263         * @ticket 22692
     264         */
     265        function test_apos_before_digits() {
     266                $input  = array();
     267                $output = array();
     268
     269                // Apostrophe before a number always becomes &#8217 (apos);
     270
     271                $input[]  = "word '99 word";
     272                $output[] = "word &#8217;99 word";
     273
     274                $input[]  = "word'99 word";
     275                $output[] = "word&#8217;99 word";
     276
     277                $input[]  = "word '99word";
     278                $output[] = "word &#8217;99word";
     279
     280                $input[]  = "word'99word";
     281                $output[] = "word&#8217;99word";
     282
     283                $input[]  = "word '99&#8217;s word"; // Appears as a separate but logically superfluous pattern in 3.8.
     284                $output[] = "word &#8217;99&#8217;s word";
     285
     286                $input[]  = "word '99's word"; // Due to the logic error, second apos becomes a prime.  See ticket #22823
     287                $output[] = "word &#8217;99&#8242;s word";
     288
     289                $input[]  = "word '99'samsonite";
     290                $output[] = "word &#8217;99&#8242;samsonite";
     291
     292                $input[]  = "according to our source, '33% of all students scored less than 50' on the test."; // Apostrophes and primes have priority over quotes
     293                $output[] = "according to our source, &#8217;33% of all students scored less than 50&#8242; on the test.";
     294
     295                $input[]  = "word '99' word"; // See ticket #8775
     296                $output[] = "word &#8217;99&#8242; word";
     297
     298                foreach($input as $key => $in) {
     299                        $this->assertEquals( $output[$key], wptexturize( $in ) );
     300                }
     301        }
     302
     303        /**
     304         * Check all baseline patterns.  If anything ever changes in wptexturize(), these tests may fail.
     305         *
     306         * @ticket 22692
     307         */
     308        function test_opening_single_quote() {
     309                $input  = array();
     310                $output = array();
     311
     312                // Apostrophe after a space or ([{<" becomes &#8216; (opening_single_quote)
     313
     314                $input[]  = "word 'word word";
     315                $output[] = "word &#8216;word word";
     316
     317                $input[]  = "word ('word word";
     318                $output[] = "word (&#8216;word word";
     319
     320                $input[]  = "word ['word word";
     321                $output[] = "word [&#8216;word word";
     322
     323                $input[]  = "word <'word word"; // Invalid HTML input?
     324                $output[] = "word <&#8216;word word";
     325
     326                $input[]  = "word &lt;'word word"; // Valid HTML input triggers the apos in a word pattern
     327                $output[] = "word &lt;&#8217;word word";
     328
     329                $input[]  = "word {'word word";
     330                $output[] = "word {&#8216;word word";
     331
     332                $input[]  = "word \"'word word";
     333                $output[] = "word &#8220;&#8216;word word"; // Two opening quotes
     334
     335                $input[]  = "'word word";
     336                $output[] = "&#8216;word word";
     337
     338                $input[]  = "word('word word";
     339                $output[] = "word(&#8216;word word";
     340
     341                $input[]  = "word['word word";
     342                $output[] = "word[&#8216;word word";
     343
     344                $input[]  = "word<'word word";
     345                $output[] = "word<&#8216;word word";
     346
     347                $input[]  = "word&lt;'word word";
     348                $output[] = "word&lt;&#8217;word word";
     349
     350                $input[]  = "word{'word word";
     351                $output[] = "word{&#8216;word word";
     352
     353                $input[]  = "word\"'word word";
     354                $output[] = "word&#8221;&#8216;word word"; // Closing quote, then opening quote
     355
     356                $input[]  = "word ' word word";
     357                $output[] = "word &#8216; word word";
     358
     359                $input[]  = "word (' word word";
     360                $output[] = "word (&#8216; word word";
     361
     362                $input[]  = "word [' word word";
     363                $output[] = "word [&#8216; word word";
     364
     365                $input[]  = "word <' word word"; // Invalid HTML input?
     366                $output[] = "word <&#8216; word word";
     367
     368                $input[]  = "word &lt;' word word"; // Valid HTML input triggers the closing single quote here
     369                $output[] = "word &lt;&#8217; word word";
     370
     371                $input[]  = "word {' word word";
     372                $output[] = "word {&#8216; word word";
     373
     374                $input[]  = "word \"' word word";
     375                $output[] = "word &#8220;&#8216; word word"; // Two opening quotes
     376
     377                $input[]  = "' word word";
     378                $output[] = "&#8216; word word";
     379
     380                $input[]  = "word(' word word";
     381                $output[] = "word(&#8216; word word";
     382
     383                $input[]  = "word[' word word";
     384                $output[] = "word[&#8216; word word";
     385
     386                $input[]  = "word<' word word";
     387                $output[] = "word<&#8216; word word";
     388
     389                $input[]  = "word&lt;' word word";
     390                $output[] = "word&lt;&#8217; word word";
     391
     392                $input[]  = "word{' word word";
     393                $output[] = "word{&#8216; word word";
     394
     395                $input[]  = "word\"' word word";
     396                $output[] = "word&#8221;&#8216; word word"; // Closing quote, then opening quote
     397
     398                foreach($input as $key => $in) {
     399                        $this->assertEquals( $output[$key], wptexturize( $in ) );
     400                }
     401        }
     402
     403        /**
     404         * Check all baseline patterns.  If anything ever changes in wptexturize(), these tests may fail.
     405         *
     406         * @ticket 22692
     407         */
     408        function test_double_prime() {
     409                $input  = array();
     410                $output = array();
     411
     412                // Double quote after a number becomes &#8243; (double_prime)
     413
     414                $input[]  = 'word 99" word';
     415                $output[] = 'word 99&#8243; word';
     416
     417                $input[]  = 'word 99"word';
     418                $output[] = 'word 99&#8243;word';
     419
     420                $input[]  = 'word99" word';
     421                $output[] = 'word99&#8243; word';
     422
     423                $input[]  = 'word99"word';
     424                $output[] = 'word99&#8243;word';
     425
     426                foreach($input as $key => $in) {
     427                        $this->assertEquals( $output[$key], wptexturize( $in ) );
     428                }
     429        }
     430
     431        /**
     432         * Check all baseline patterns.  If anything ever changes in wptexturize(), these tests may fail.
     433         *
     434         * @ticket 22692
     435         */
     436        function test_single_prime() {
     437                $input  = array();
     438                $output = array();
     439
     440                // Apostrophe after a number becomes &#8242; (prime)
     441
     442                $input[]  = "word 99' word";
     443                $output[] = "word 99&#8242; word";
     444
     445                $input[]  = "word 99'word";
     446                $output[] = "word 99&#8242;word";
     447
     448                $input[]  = "word99' word";
     449                $output[] = "word99&#8242; word";
     450
     451                $input[]  = "word99'word";
     452                $output[] = "word99&#8242;word";
     453
     454                foreach($input as $key => $in) {
     455                        $this->assertEquals( $output[$key], wptexturize( $in ) );
     456                }
     457        }
     458
     459        /**
     460         * Check all baseline patterns.  If anything ever changes in wptexturize(), these tests may fail.
     461         *
     462         * @ticket 22692
     463         */
     464        function test_contractions() {
     465                $input  = array();
     466                $output = array();
     467
     468                // Apostrophe "in a word" becomes &#8217; (apos)
     469
     470                $input[]  = "word word's word";
     471                $output[] = "word word&#8217;s word";
     472
     473                $input[]  = "word word'. word"; // Quotes with outside punctuation could end with apostrophes instead of closing quotes (may affect i18n)
     474                $output[] = "word word&#8217;. word";
     475
     476                $input[]  = "word ]'. word";
     477                $output[] = "word ]&#8217;. word";
     478
     479                $input[]  = "word )'. word";
     480                $output[] = "word )&#8217;. word";
     481
     482                $input[]  = "word }'. word";
     483                $output[] = "word }&#8217;. word";
     484
     485                $input[]  = "word >'. word"; // Not tested
     486                $output[] = "word >&#8217;. word";
     487
     488                $input[]  = "word &gt;'. word";
     489                $output[] = "word &gt;&#8217;. word";
     490
     491                foreach($input as $key => $in) {
     492                        $this->assertEquals( $output[$key], wptexturize( $in ) );
     493                }
     494        }
     495
     496        /**
     497         * Check all baseline patterns.  If anything ever changes in wptexturize(), these tests may fail.
     498         *
     499         * @ticket 22692
     500         */
     501        function test_opening_quote() {
     502                $input  = array();
     503                $output = array();
     504
     505                // Double quote after a space or ([{< becomes &#8220; (opening_quote) if not followed by spaces
     506
     507                $input[]  = 'word "word word';
     508                $output[] = 'word &#8220;word word';
     509
     510                $input[]  = 'word ("word word';
     511                $output[] = 'word (&#8220;word word';
     512
     513                $input[]  = 'word ["word word';
     514                $output[] = 'word [&#8220;word word';
     515
     516                $input[]  = 'word <"word word'; // Invalid HTML input?
     517                $output[] = 'word <&#8220;word word';
     518
     519                $input[]  = 'word &lt;"word word'; // Valid HTML input triggers the closing quote pattern
     520                $output[] = 'word &lt;&#8221;word word';
     521
     522                $input[]  = 'word {"word word';
     523                $output[] = 'word {&#8220;word word';
     524
     525                $input[]  = '"word word';
     526                $output[] = '&#8220;word word';
     527
     528                $input[]  = 'word("word word';
     529                $output[] = 'word(&#8220;word word';
     530
     531                $input[]  = 'word["word word';
     532                $output[] = 'word[&#8220;word word';
     533
     534                $input[]  = 'word<"word word'; // Invalid HTML input?
     535                $output[] = 'word<&#8220;word word';
     536
     537                $input[]  = 'word&lt;"word word'; // Valid HTML input triggers the closing quote pattern
     538                $output[] = 'word&lt;&#8221;word word';
     539
     540                $input[]  = 'word{"word word';
     541                $output[] = 'word{&#8220;word word';
     542
     543                $input[]  = 'word "99 word';
     544                $output[] = 'word &#8220;99 word';
     545
     546                foreach($input as $key => $in) {
     547                        $this->assertEquals( $output[$key], wptexturize( $in ) );
     548                }
     549        }
     550
     551        /**
     552         * Check all baseline patterns.  If anything ever changes in wptexturize(), these tests may fail.
     553         *
     554         * @ticket 22692
     555         */
     556        function test_closing_quote() {
     557                $input  = array();
     558                $output = array();
     559
     560                // Double quote becomes &#8221; (closing_quote) unless it is already converted to double_prime or opening_quote.
     561
     562                $input[]  = 'word word" word';
     563                $output[] = 'word word&#8221; word';
     564
     565                $input[]  = 'word word") word';
     566                $output[] = 'word word&#8221;) word';
     567
     568                $input[]  = 'word word"] word';
     569                $output[] = 'word word&#8221;] word';
     570
     571                $input[]  = 'word word"} word';
     572                $output[] = 'word word&#8221;} word';
     573
     574                $input[]  = 'word word"> word'; // Invalid HTML input?
     575                $output[] = 'word word&#8221;> word';
     576
     577                $input[]  = 'word word"&gt; word'; // Valid HTML should work
     578                $output[] = 'word word&#8221;&gt; word';
     579
     580                $input[]  = 'word word"';
     581                $output[] = 'word word&#8221;';
     582
     583                $input[]  = 'word word"word';
     584                $output[] = 'word word&#8221;word';
     585
     586                $input[]  = 'word"word"word';
     587                $output[] = 'word&#8221;word&#8221;word';
     588
     589                $input[]  = 'test sentence".';
     590                $output[] = 'test sentence&#8221;.';
     591
     592                $input[]  = 'test sentence."';
     593                $output[] = 'test sentence.&#8221;';
     594
     595                $input[]  = 'test sentence". word';
     596                $output[] = 'test sentence&#8221;. word';
     597
     598                $input[]  = 'test sentence." word';
     599                $output[] = 'test sentence.&#8221; word';
     600
     601                foreach($input as $key => $in) {
     602                        $this->assertEquals( $output[$key], wptexturize( $in ) );
     603                }
     604        }
     605
     606        /**
     607         * Check all baseline patterns.  If anything ever changes in wptexturize(), these tests may fail.
     608         *
     609         * @ticket 22692
     610         */
     611        function test_closing_single_quote() {
     612                $input  = array();
     613                $output = array();
     614
     615                // Single quote followed by a space or a period becomes &#8217; (closing_single_quote)
     616
     617                $input[]  = "word word' word";
     618                $output[] = "word word&#8217; word";
     619
     620                $input[]  = "word word'. word";
     621                $output[] = "word word&#8217;. word";
     622
     623                $input[]  = "word word'.word";
     624                $output[] = "word word&#8217;.word";
     625
     626                $input[]  = "word word'";
     627                $output[] = "word word&#8217;";
     628
     629                $input[]  = "test sentence'.";
     630                $output[] = "test sentence&#8217;.";
     631
     632                $input[]  = "test sentence.'";
     633                $output[] = "test sentence.&#8217;";
     634
     635                $input[]  = "test sentence'. word";
     636                $output[] = "test sentence&#8217;. word";
     637
     638                $input[]  = "test sentence.' word";
     639                $output[] = "test sentence.&#8217; word";
     640
     641                foreach($input as $key => $in) {
     642                        $this->assertEquals( $output[$key], wptexturize( $in ) );
     643                }
     644        }
     645
     646        /**
     647         * Check all baseline patterns.  If anything ever changes in wptexturize(), these tests may fail.
     648         *
     649         * @ticket 22692
     650         */
     651        function test_multiplication() {
     652                $input  = array();
     653                $output = array();
     654
     655                // 9x9 becomes 9&#215;9
     656
     657                $input[]  = "9x9";
     658                $output[] = "9&#215;9";
     659
     660                $input[]  = "12x34";
     661                $output[] = "12&#215;34";
     662
     663                $input[]  = "9 x 9";
     664                $output[] = "9 x 9";
     665
     666                foreach($input as $key => $in) {
     667                        $this->assertEquals( $output[$key], wptexturize( $in ) );
     668                }
     669        }
     670
     671        /**
     672         * Check all baseline patterns.  If anything ever changes in wptexturize(), these tests may fail.
     673         *
     674         * @ticket 22692
     675         */
     676        function test_ampersand() {
     677                $input  = array();
     678                $output = array();
     679
     680                // & always becomes &#038; unless it is followed by # or ;
     681
     682                $input[]  = "word & word";
     683                $output[] = "word &#038; word";
     684
     685                $input[]  = "word&word";
     686                $output[] = "word&#038;word";
     687
     688                $input[]  = "word &nbsp; word";
     689                $output[] = "word &nbsp; word";
     690
     691                $input[]  = "word &#038; word";
     692                $output[] = "word &#038; word";
     693
     694                $input[]  = "word &# word";
     695                $output[] = "word &# word"; // invalid output?
     696
     697                $input[]  = "word &44; word";
     698                $output[] = "word &44; word";
     699
     700                foreach($input as $key => $in) {
     701                        $this->assertEquals( $output[$key], wptexturize( $in ) );
     702                }
     703        }
     704
     705        /**
     706         * Check all baseline patterns.  If anything ever changes in wptexturize(), these tests may fail.
     707         *
     708         * @ticket 22692
     709         */
     710        function test_cockney() {
     711                $input  = array();
     712                $output = array();
     713
     714                // "cockney" phrases begin with apos instead of opening_single_quote.
     715
     716                $input[]  = "word 'tain't word";
     717                $output[] = "word &#8217;tain&#8217;t word";
     718
     719                $input[]  = "word 'twere word";
     720                $output[] = "word &#8217;twere word";
     721
     722                $input[]  = "word 'twas word";
     723                $output[] = "word &#8217;twas word";
     724
     725                $input[]  = "word 'tis word";
     726                $output[] = "word &#8217;tis word";
     727
     728                $input[]  = "word 'twill word";
     729                $output[] = "word &#8217;twill word";
     730
     731                $input[]  = "word 'til word";
     732                $output[] = "word &#8217;til word";
     733
     734                $input[]  = "word 'bout word";
     735                $output[] = "word &#8217;bout word";
     736
     737                $input[]  = "word 'nuff word";
     738                $output[] = "word &#8217;nuff word";
     739
     740                $input[]  = "word 'round word";
     741                $output[] = "word &#8217;round word";
     742
     743                $input[]  = "word 'cause word";
     744                $output[] = "word &#8217;cause word";
     745
     746                $input[]  = "word 'em word";
     747                $output[] = "word &#8216;em word";
     748
     749                foreach($input as $key => $in) {
     750                        $this->assertEquals( $output[$key], wptexturize( $in ) );
     751                }
     752        }
     753
     754        /**
     755         * Check all baseline patterns.  If anything ever changes in wptexturize(), these tests may fail.
     756         *
     757         * @ticket 22692
     758         */
     759        function test_smart_dashes() {
     760                $input  = array();
     761                $output = array();
     762
     763                // Smart dashes, etc
     764
     765                $input[]  = "word --- word";
     766                $output[] = "word &#8212; word";
     767
     768                $input[]  = "word---word";
     769                $output[] = "word&#8212;word";
     770
     771                $input[]  = "word -- word";
     772                $output[] = "word &#8212; word";
     773
     774                $input[]  = "word--word";
     775                $output[] = "word&#8211;word";
     776
     777                $input[]  = "word - word";
     778                $output[] = "word &#8211; word";
     779
     780                $input[]  = "word-word";
     781                $output[] = "word-word";
     782
     783                $input[]  = "word xn&#8211; word";
     784                $output[] = "word xn-- word";
     785
     786                $input[]  = "wordxn&#8211;word";
     787                $output[] = "wordxn--word";
     788
     789                foreach($input as $key => $in) {
     790                        $this->assertEquals( $output[$key], wptexturize( $in ) );
     791                }
     792        }
     793
     794        /**
     795         * Check all baseline patterns.  If anything ever changes in wptexturize(), these tests may fail.
     796         *
     797         * @ticket 22692
     798         */
     799        function test_misc_static_replacements() {
     800                $input  = array();
     801                $output = array();
     802
     803                $input[]  = "word ... word";
     804                $output[] = "word &#8230; word";
     805
     806                $input[]  = "word...word";
     807                $output[] = "word&#8230;word";
     808
     809                $input[]  = "word `` word";
     810                $output[] = "word &#8220; word";
     811
     812                $input[]  = "word``word";
     813                $output[] = "word&#8220;word";
     814
     815                $input[]  = "word '' word";
     816                $output[] = "word &#8221; word";
     817
     818                $input[]  = "word''word";
     819                $output[] = "word&#8221;word";
     820
     821                $input[]  = "word (tm) word";
     822                $output[] = "word &#8482; word";
     823
     824                $input[]  = "word (tm)word";
     825                $output[] = "word &#8482;word";
     826
     827                $input[]  = "word(tm) word";
     828                $output[] = "word(tm) word";
     829
     830                $input[]  = "word(tm)word";
     831                $output[] = "word(tm)word";
     832
     833                foreach($input as $key => $in) {
     834                        $this->assertEquals( $output[$key], wptexturize( $in ) );
     835                }
     836        }
     837
     838
     839        /**
     840         * All of these tests fail against 3.8 but were not yet listed above.
     841         *
     842         * @ticket 22692
     843         */
     844        function test_more_bugs() {
     845                $input  = array();
     846                $output = array();
     847
     848                // Tests derived from, and contrary to, the baseline patterns above, where output seemed unusual
     849
     850                $input[]  = "according to our source, '33% of all students scored less than 50' on the test.";
     851                $output[] = "according to our source, &#8216;33% of all students scored less than 50&#8217; on the test.";
     852
     853                $input[]  = 'according to our source, "33% of all students scored less than 50" on the test.';
     854                $output[] = 'according to our source, &#8220;33% of all students scored less than 50&#8221; on the test.';
     855
     856                $input[]  = "word &lt;'test quote'&rt; word";
     857                $output[] = "word &lt;&#8216;test quote&#8217;&rt; word";
     858
     859                $input[]  = 'word &lt;"test quote"&rt; word';
     860                $output[] = 'word &lt;&#8220;test quote&#8221;&rt; word';
     861
     862                $input[]  = "word 'em word";
     863                $output[] = "word &#8217;em word";
     864
     865                $input[]  = "word xn&#8211; word";
     866                $output[] = "word xn&#8211; word";
     867
     868                $input[]  = "wordxn&#8211;word";
     869                $output[] = "wordxn&#8211;word";
     870
     871                foreach($input as $key => $in) {
     872                        $this->assertEquals( $output[$key], wptexturize( $in ) );
     873                }
     874        }
     875
     876        /**
     877         * Multiplication pattern in 3.8 will break HTML that contains matching server names or directories.
     878         *
     879         * @ticket 4116
     880         */
     881        function test_multiplication_in_urls() {
     882                $input  = array();
     883                $output = array();
     884
     885                $input[]  = "www.4x3.com";
     886                $output[] = "www.4x3.com";
     887
     888                $input[]  = "4x3.domain.com";
     889                $output[] = "4x3.domain.com";
     890
     891                $input[]  = "<a href='http://www.24x7.com/'>http://www.24x7.com/</a>";
     892                $output[] = "<a href='http://www.24x7.com/'>http://www.24x7.com/</a>";
     893
     894                $input[]  = "<a href='http://www.domain.com/24x7/'>http://www.domain.com/24x7/</a>";
     895                $output[] = "<a href='http://www.domain.com/24x7/'>http://www.domain.com/24x7/</a>";
     896
     897                foreach($input as $key => $in) {
     898                        $this->assertEquals( $output[$key], wptexturize( $in ) );
     899                }
     900        }
     901
     902        /**
     903         * Shortcodes and smart quotes might conflict.  Some of these appear to be fixed already.
     904         *
     905         * @ticket 6969
     906         */
     907        function test_quotes_in_shortcodes() {
     908                $input  = array();
     909                $output = array();
     910
     911                $input[]  = '[caption]<img src="http://localhost/Great_Wave.jpg" alt="Great Wave" title="Great Wave" width="300" height="205" /> The Great Wave[/caption]';
     912                $output[] = '[caption]<img src="http://localhost/Great_Wave.jpg" alt="Great Wave" title="Great Wave" width="300" height="205" /> The Great Wave[/caption]';
     913
     914                $input[]  = '[code lang="php"]$foo = \'bar\';[/code]';
     915                $output[] = '[code lang="php"]$foo = \'bar\';[/code]';
     916
     917                $input[]  = '[foobar]This is how you "quote" things.[/foobar]';
     918                $output[] = '[foobar]This is how you "quote" things.[/foobar]';
     919
     920                $input[]  = "<pre>\n[[php foo=\"bar\"]\necho \"foo\" . 'bar';\n[/php]]\n</pre>";
     921                $output[] = "<pre>\n[[php foo=\"bar\"]\necho \"foo\" . 'bar';\n[/php]]\n</pre>";
     922
     923                $input[]  = "foo[shortcode]\n\"bar\"\n[/shortcode]foo";
     924                $output[] = "foo[shortcode]\n\"bar\"\n[/shortcode]foo";
     925
     926                foreach($input as $key => $in) {
     927                        $this->assertEquals( $output[$key], wptexturize( $in ) );
     928                }
     929        }
     930
     931        /**
     932         * User requested smart quotes not break when surrounded by dashes.
     933         *
     934         * @ticket 20342
     935         */
     936        function test_dashes_around_quotes() {
     937                $input  = array();
     938                $output = array();
     939
     940                // These may fail in 3.8
     941
     942                $input[]  = 'word---"quote"';
     943                $output[] = 'word&#8212;&#8220;quote&#8221;';
     944
     945                $input[]  = 'word--"quote"';
     946                $output[] = 'word&#8211;&#8220;quote&#8221;';
     947
     948                $input[]  = 'word-"quote"';
     949                $output[] = 'word-&#8220;quote&#8221;';
     950
     951                // These should pass already
     952
     953                $input[]  = '"quote"---word';
     954                $output[] = '&#8220;quote&#8221;&#8212;word';
     955
     956                $input[]  = '"quote"--word';
     957                $output[] = '&#8220;quote&#8221;&#8211;word';
     958
     959                $input[]  = '"quote"-word';
     960                $output[] = '&#8220;quote&#8221;-word';
     961
     962                foreach($input as $key => $in) {
     963                        $this->assertEquals( $output[$key], wptexturize( $in ) );
     964                }
     965        }
     966
     967        /**
     968         * Numbers after apostrophes are ambiguous due to the ambiguity of single quotes.
     969         *
     970         * @ticket 26850
     971         */
     972        function test_quotes_starting_with_digits() {
     973                $input  = array();
     974                $output = array();
     975
     976                $input[]  = "in '4 years, 3 months,' Obama cut the deficit";
     977                $output[] = "in &#8216;4 years, 3 months,&#8217; Obama cut the deficit";
     978
     979                $input[]  = "in '40 years, 3 months,' Obama cut the deficit";
     980                $output[] = "in &#8216;40 years, 3 months,&#8217; Obama cut the deficit";
     981
     982                $input[]  = "in '400 years, 3 months,' Obama cut the deficit";
     983                $output[] = "in &#8216;400 years, 3 months,&#8217; Obama cut the deficit";
     984
     985                foreach($input as $key => $in) {
     986                        $this->assertEquals( $output[$key], wptexturize( $in ) );
     987                }
     988        }
    197989}
  • tests/phpunit/tests/shortcode.php

     
    373373                remove_filter( 'shortcode_atts_bartag', array( $this, '_filter_atts2' ), 10, 3 );
    374374        }
    375375
     376        /**
     377         * Check that shortcode_unautop() will always recognize spaces around shortcodes.
     378         *
     379         * @ticket 22692
     380         */
     381        function test_spaces_around_shortcodes() {
     382                $nbsp = "\xC2\xA0";
     383
     384                $input  = array();
     385
     386                $input[] = "<p>[gallery ids=\"37,15,11\"]</p>";
     387                $input[] = "<p> [gallery ids=\"37,15,11\"] </p>";
     388                $input[] = "<p> {$nbsp}[gallery ids=\"37,15,11\"] {$nbsp}</p>";
     389                $input[] = "<p> &nbsp;[gallery ids=\"37,15,11\"] &nbsp;</p>";
     390
     391                $output = "[gallery ids=\"37,15,11\"]";
     392
     393                foreach($input as $in) {
     394                        $this->assertEquals( $output, shortcode_unautop( $in ) );
     395                }
     396        }
    376397}