WordPress.org

Make WordPress Core

Changeset 25313


Ignore:
Timestamp:
09/10/2013 03:17:51 AM (8 years ago)
Author:
wonderboymusic
Message:

Replace the ancient phpfreaks.com RegEx to extract urls to ping with a more robust matcher. URLs with commas and things like & were not being pinged. The new matcher even works for most IDN URLs. Adds unit tests.

Fixes #9064.

Location:
trunk
Files:
3 edited

Legend:

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

    r25139 r25313  
    18281828    $pung = get_pung($post_ID);
    18291829
    1830     // Variables
    1831     $ltrs = '\w';
    1832     $gunk = '/#~:.?+=&%@!\-';
    1833     $punc = '.:?\-';
    1834     $any = $ltrs . $gunk . $punc;
    1835 
    18361830    // Step 1
    18371831    // Parsing the post, external links (if any) are stored in the $post_links array
    1838     // This regexp comes straight from phpfreaks.com
    1839     // http://www.phpfreaks.com/quickcode/Extract_All_URLs_on_a_Page/15.php
    1840     preg_match_all("{\b http : [$any] +? (?= [$punc] * [^$any] | $)}x", $content, $post_links_temp);
     1832    $post_links_temp = wp_extract_urls( $content );
    18411833
    18421834    // Step 2.
     
    18491841    // We don't wanna ping first and second types, even if they have a valid <link/>
    18501842
    1851     foreach ( (array) $post_links_temp[0] as $link_test ) :
     1843    foreach ( (array) $post_links_temp as $link_test ) :
    18521844        if ( !in_array($link_test, $pung) && (url_to_postid($link_test) != $post_ID) // If we haven't pung it already and it isn't a link to itself
    18531845                && !is_local_attachment($link_test) ) : // Also, let's never ping local attachments.
  • trunk/src/wp-includes/functions.php

    r25190 r25313  
    394394
    395395/**
     396 * Use RegEx to extract URLs from arbitrary content
     397 *
     398 * @since 3.7.0
     399 *
     400 * @param string $content
     401 * @return array URLs found in passed string
     402 */
     403function wp_extract_urls( $content ) {
     404    preg_match_all(
     405        "#((?:[\w-]+://?|[\w\d]+[.])[^\s()<>]+[.](?:\([\w\d]+\)|(?:[^`!()\[\]{};:'\".,<>?«»“”‘’\s]|(?:[:]\d+)?/?)+))#",
     406        $content,
     407        $post_links
     408    );
     409
     410    $post_links = array_unique( array_map( 'html_entity_decode', $post_links[0] ) );
     411
     412    return array_values( $post_links );
     413}
     414
     415/**
    396416 * Check content for video and audio links to add as enclosures.
    397417 *
     
    418438    $pung = get_enclosed( $post_ID );
    419439
    420     $ltrs = '\w';
    421     $gunk = '/#~:.?+=&%@!\-';
    422     $punc = '.:?\-';
    423     $any = $ltrs . $gunk . $punc;
    424 
    425     preg_match_all( "{\b https? : [$any] +? (?= [$punc] * [^$any] | $)}x", $content, $post_links_temp );
     440    $post_links_temp = wp_extract_urls( $content );
    426441
    427442    foreach ( $pung as $link_test ) {
    428         if ( !in_array( $link_test, $post_links_temp[0] ) ) { // link no longer in post
     443        if ( ! in_array( $link_test, $post_links_temp ) ) { // link no longer in post
    429444            $mids = $wpdb->get_col( $wpdb->prepare("SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE (%s)", $post_ID, like_escape( $link_test ) . '%') );
    430445            foreach ( $mids as $mid )
     
    433448    }
    434449
    435     foreach ( (array) $post_links_temp[0] as $link_test ) {
     450    foreach ( (array) $post_links_temp as $link_test ) {
    436451        if ( !in_array( $link_test, $pung ) ) { // If we haven't pung it already
    437452            $test = @parse_url( $link_test );
  • trunk/tests/phpunit/tests/functions.php

    r25301 r25313  
    100100
    101101    function test_wp_unique_filename() {
    102        
     102
    103103        $testdir = DIR_TESTDATA . '/images/';
    104        
     104
    105105        // sanity check
    106106        $this->assertEquals( 'abcdefg.png', wp_unique_filename( $testdir, 'abcdefg.png' ), 'Sanitiy check failed' );
     
    113113        // check special chars
    114114        $this->assertEquals( 'testtést-imagé.png', wp_unique_filename( $testdir, 'testtést-imagé.png' ), 'Filename with special chars failed' );
    115        
     115
    116116        // check special chars with potential conflicting name
    117117        $this->assertEquals( 'tést-imagé.png', wp_unique_filename( $testdir, 'tést-imagé.png' ), 'Filename with special chars failed' );
    118        
     118
    119119        // check with single quotes in name (somehow)
    120120        $this->assertEquals( "abcdefgh.png", wp_unique_filename( $testdir, "abcdefg'h.png" ), 'File with quote failed' );
     
    125125        // test crazy name (useful for regression tests)
    126126        $this->assertEquals( '12%af34567890@..%^_+qwerty-fghjkl-zx.png', wp_unique_filename( $testdir, '12%af34567890#~!@#$..%^&*()|_+qwerty  fgh`jkl zx<>?:"{}[]="\'/?.png' ), 'Failed crazy file name' );
    127        
     127
    128128        // test slashes in names
    129129        $this->assertEquals( 'abcdefg.png', wp_unique_filename( $testdir, 'abcde\fg.png' ), 'Slash not removed' );
     
    363363        $this->assertNotContains( 'data', wp_allowed_protocols() );
    364364    }
     365
     366    /**
     367     * @ticket 9064
     368     */
     369    function test_wp_extract_urls() {
     370        $original_urls = array(
     371            'http://woo.com/1,2,3,4,5,6/-1-2-3-4-/woo.html',
     372            'http://this.com',
     373            'http://www111.urwyeoweytwutreyytqytwetowteuiiu.com/?346236346326&2134362574863.437',
     374            'http://wordpress-core/1,2,3,4,5,6/-1-2-3-4-/woo.html',
     375            'http://wordpress-core.com:8080/',
     376            'http://www.website.com:5000',
     377            'http://wordpress-core/?346236346326&2134362574863.437',
     378            'http://افغانستا.icom.museum',
     379            'http://الجزائر.icom.museum',
     380            'http://österreich.icom.museum',
     381            'http://বাংলাদেশ.icom.museum',
     382            'http://беларусь.icom.museum',
     383            'http://belgië.icom.museum',
     384            'http://българия.icom.museum',
     385            'http://تشادر.icom.museum',
     386            'http://中国.icom.museum',
     387            #'http://القمر.icom.museum', // Comoros http://القمر.icom.museum
     388            #'http://κυπρος.icom.museum', Cyprus    http://κυπρος.icom.museum
     389            'http://českárepublika.icom.museum',
     390            #'http://مصر.icom.museum', // Egypt http://مصر.icom.museum
     391            'http://ελλάδα.icom.museum',
     392            'http://magyarország.icom.museum',
     393            'http://ísland.icom.museum',
     394            'http://भारत.icom.museum',
     395            'http://ايران.icom.museum',
     396            'http://éire.icom.museum',
     397            'http://איקו״ם.ישראל.museum',
     398            'http://日本.icom.museum',
     399            'http://الأردن.icom.museum',
     400            'http://қазақстан.icom.museum',
     401            'http://한국.icom.museum',
     402            'http://кыргызстан.icom.museum',
     403            'http://ລາວ.icom.museum',
     404            'http://لبنان.icom.museum',
     405            'http://македонија.icom.museum',
     406            #'http://موريتانيا.icom.museum', // Mauritania  http://موريتانيا.icom.museum
     407            'http://méxico.icom.museum',
     408            'http://монголулс.icom.museum',
     409            #'http://المغرب.icom.museum', // Morocco    http://المغرب.icom.museum
     410            'http://नेपाल.icom.museum',
     411            #'http://عمان.icom.museum', // Oman http://عمان.icom.museum
     412            'http://قطر.icom.museum',
     413            'http://românia.icom.museum',
     414            'http://россия.иком.museum',
     415            'http://србијаицрнагора.иком.museum',
     416            'http://இலங்கை.icom.museum',
     417            'http://españa.icom.museum',
     418            'http://ไทย.icom.museum',
     419            'http://تونس.icom.museum',
     420            'http://türkiye.icom.museum',
     421            'http://украина.icom.museum',
     422            'http://việtnam.icom.museum'
     423        );
     424
     425        $blob ="
     426            http://woo.com/1,2,3,4,5,6/-1-2-3-4-/woo.html
     427
     428            http://this.com
     429
     430            http://www111.urwyeoweytwutreyytqytwetowteuiiu.com/?346236346326&amp;2134362574863.437
     431
     432            http://wordpress-core/1,2,3,4,5,6/-1-2-3-4-/woo.html
     433
     434            http://wordpress-core.com:8080/
     435
     436            http://www.website.com:5000
     437
     438            http://wordpress-core/?346236346326&amp;2134362574863.437
     439
     440            http://افغانستا.icom.museum
     441            http://الجزائر.icom.museum
     442            http://österreich.icom.museum
     443            http://বাংলাদেশ.icom.museum
     444            http://беларусь.icom.museum
     445            http://belgië.icom.museum
     446            http://българия.icom.museum
     447            http://تشادر.icom.museum
     448            http://中国.icom.museum
     449            http://českárepublika.icom.museum
     450            http://ελλάδα.icom.museum
     451            http://magyarország.icom.museum
     452            http://ísland.icom.museum
     453            http://भारत.icom.museum
     454            http://ايران.icom.museum
     455            http://éire.icom.museum
     456            http://איקו״ם.ישראל.museum
     457            http://日本.icom.museum
     458            http://الأردن.icom.museum
     459            http://қазақстан.icom.museum
     460            http://한국.icom.museum
     461            http://кыргызстан.icom.museum
     462            http://ລາວ.icom.museum
     463            http://لبنان.icom.museum
     464            http://македонија.icom.museum
     465            http://méxico.icom.museum
     466            http://монголулс.icom.museum
     467            http://नेपाल.icom.museum
     468            http://قطر.icom.museum
     469            http://românia.icom.museum
     470            http://россия.иком.museum
     471            http://србијаицрнагора.иком.museum
     472            http://இலங்கை.icom.museum
     473            http://españa.icom.museum
     474            http://ไทย.icom.museum
     475            http://تونس.icom.museum
     476            http://türkiye.icom.museum
     477            http://украина.icom.museum
     478            http://việtnam.icom.museum
     479        ";
     480
     481        $urls = wp_extract_urls( $blob );
     482        $this->assertNotEmpty( $urls );
     483        $this->assertInternalType( 'array', $urls );
     484        $this->assertCount( count( $original_urls ), $urls );
     485        $this->assertEquals( $original_urls, $urls );
     486
     487        $exploded = array_values( array_filter( array_map( 'trim', explode( "\n", $blob ) ) ) );
     488        // wp_extract_urls calls html_entity_decode
     489        $decoded = array_map( 'html_entity_decode', $exploded );
     490
     491        $this->assertEquals( $decoded, $urls );
     492        $this->assertEquals( $original_urls, $decoded );
     493
     494        $blob ="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
     495            incididunt ut labore http://woo.com/1,2,3,4,5,6/-1-2-3-4-/woo.html et dolore magna aliqua.
     496            Ut http://this.com enim ad minim veniam, quis nostrud exercitation ullamco
     497            laboris nisi ut aliquip ex http://www111.urwyeoweytwutreyytqytwetowteuiiu.com/?346236346326&amp;2134362574863.437 ea
     498            commodo consequat. http://wordpress-core/1,2,3,4,5,6/-1-2-3-4-/woo.html Duis aute irure dolor in reprehenderit in voluptate
     499            velit esse http://wordpress-core.com:8080/ cillum dolore eu fugiat nulla <A href=\"http://www.website.com:5000\">http://www.website.com:5000</B> pariatur. Excepteur sint occaecat cupidatat non proident,
     500            sunt in culpa qui officia deserunt mollit http://wordpress-core/?346236346326&amp;2134362574863.437 anim id est laborum.";
     501
     502        $urls = wp_extract_urls( $blob );
     503        $this->assertNotEmpty( $urls );
     504        $this->assertInternalType( 'array', $urls );
     505        $this->assertCount( 7, $urls );
     506        $this->assertEquals( array_slice( $original_urls, 0, 7 ), $urls );
     507
     508        $blob = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
     509            incididunt ut labore <a href="http://woo.com/1,2,3,4,5,6/-1-2-3-4-/woo.html">343462^</a> et dolore magna aliqua.
     510            Ut <a href="http://this.com">&amp;3640i6p1yi499</a> enim ad minim veniam, quis nostrud exercitation ullamco
     511            laboris nisi ut aliquip ex <a href="http://www111.urwyeoweytwutreyytqytwetowteuiiu.com/?346236346326&amp;2134362574863.437">343462^</a> ea
     512            commodo consequat. <a href="http://wordpress-core/1,2,3,4,5,6/-1-2-3-4-/woo.html">343462^</a> Duis aute irure dolor in reprehenderit in voluptate
     513            velit esse <a href="http://wordpress-core.com:8080/">-3-4--321-64-4@#!$^$!@^@^</a> cillum dolore eu <A href="http://www.website.com:5000">http://www.website.com:5000</B> fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident,
     514            sunt in culpa qui officia deserunt mollit <a href="http://wordpress-core/?346236346326&amp;2134362574863.437">)(*&^%$</a> anim id est laborum.';
     515
     516        $urls = wp_extract_urls( $blob );
     517        $this->assertNotEmpty( $urls );
     518        $this->assertInternalType( 'array', $urls );
     519        $this->assertCount( 7, $urls );
     520        $this->assertEquals( array_slice( $original_urls, 0, 7 ), $urls );
     521    }
    365522}
Note: See TracChangeset for help on using the changeset viewer.