Make WordPress Core

Ticket #45067: 45067.2.diff

File 45067.2.diff, 4.6 KB (added by azaozz, 6 years ago)
  • src/wp-includes/kses.php

     
    549549        $allowed_html = wp_kses_allowed_html( 'post' );
    550550        $allowed_protocols = wp_allowed_protocols();
    551551        $string = wp_kses_no_null( $string, array( 'slash_zero' => 'keep' ) );
    552        
     552
    553553        // Preserve leading and trailing whitespace.
    554554        $matches = array();
    555555        preg_match('/^\s*/', $string, $matches);
     
    561561        } else {
    562562                $string = substr( $string, strlen( $lead ), -strlen( $trail ) );
    563563        }
    564        
     564
    565565        // Parse attribute name and value from input.
    566566        $split = preg_split( '/\s*=\s*/', $string, 2 );
    567567        $name = $split[0];
     
    598598                $value = '';
    599599                $vless = 'y';
    600600        }
    601        
     601
    602602        // Sanitize attribute by name.
    603603        wp_kses_attr_check( $name, $value, $string, $vless, $element, $allowed_html );
    604604
     
    10621062        } else {
    10631063                $xhtml_slash = '';
    10641064        }
    1065        
     1065
    10661066        // Split it
    10671067        $attrarr = wp_kses_hair_parse( $attr );
    10681068        if ( false === $attrarr ) {
     
    10721072        // Make sure all input is returned by adding front and back matter.
    10731073        array_unshift( $attrarr, $begin . $slash . $elname );
    10741074        array_push( $attrarr, $xhtml_slash . $end );
    1075        
     1075
    10761076        return $attrarr;
    10771077}
    10781078
     
    12151215 * @param array  $allowed_protocols Allowed protocols to keep
    12161216 * @return string Filtered content
    12171217 */
    1218 function wp_kses_bad_protocol($string, $allowed_protocols) {
    1219         $string = wp_kses_no_null($string);
     1218function wp_kses_bad_protocol( $string, $allowed_protocols = array() ) {
     1219        if ( empty( $allowed_protocols ) ) {
     1220                $allowed_protocols = wp_allowed_protocols();
     1221        }
     1222
     1223        $string     = wp_kses_no_null( $string );
    12201224        $iterations = 0;
    12211225
    12221226        do {
     
    16871691 * @return string            Filtered string of CSS rules.
    16881692 */
    16891693function safecss_filter_attr( $css, $deprecated = '' ) {
    1690         if ( !empty( $deprecated ) )
     1694        if ( ! empty( $deprecated ) )
    16911695                _deprecated_argument( __FUNCTION__, '2.8.1' ); // Never implemented
    16921696
    1693         $css = wp_kses_no_null($css);
    1694         $css = str_replace(array("\n","\r","\t"), '', $css);
     1697        $css = wp_kses_no_null( $css );
     1698        $css = str_replace( array( "\n", "\r", "\t" ), '', $css );
    16951699
    1696         if ( preg_match( '%[\\\\(&=}]|/\*%', $css ) ) // remove any inline css containing \ ( & } = or comments
    1697                 return '';
    1698 
    16991700        $css_array = explode( ';', trim( $css ) );
    17001701
    17011702        /**
     
    17101711        $allowed_attr = apply_filters( 'safe_style_css', array(
    17111712                'background',
    17121713                'background-color',
     1714                'background-image',
    17131715
    17141716                'border',
    17151717                'border-width',
     
    17781780                'list-style-type',
    17791781        ) );
    17801782
    1781         if ( empty($allowed_attr) )
     1783
     1784        /*
     1785         * CSS attributes that accept URL data types.
     1786         *
     1787         * This is in accordance to the CSS spec and unrelated to
     1788         * the sub-set of supported attributes above.
     1789         *
     1790         * See: https://developer.mozilla.org/en-US/docs/Web/CSS/url
     1791         */
     1792        $css_url_data_types = array(
     1793                'background',
     1794                'background-image',
     1795
     1796                'cursor',
     1797
     1798                'list-style',
     1799                'list-style-image',
     1800        );
     1801
     1802        if ( empty( $allowed_attr ) ) {
    17821803                return $css;
     1804        }
    17831805
    17841806        $css = '';
    17851807        foreach ( $css_array as $css_item ) {
    1786                 if ( $css_item == '' )
     1808                if ( $css_item == '' ) {
    17871809                        continue;
    1788                 $css_item = trim( $css_item );
    1789                 $found = false;
     1810                }
     1811
     1812                $css_item        = trim( $css_item );
     1813                $css_test_string = $css_item;
     1814                $found           = false;
     1815                $url_attr        = false;
     1816
    17901817                if ( strpos( $css_item, ':' ) === false ) {
    17911818                        $found = true;
    17921819                } else {
    1793                         $parts = explode( ':', $css_item );
    1794                         if ( in_array( trim( $parts[0] ), $allowed_attr ) )
     1820                        $parts = explode( ':', $css_item, 2 );
     1821                        $css_selector = trim( $parts[0] );
     1822
     1823                        if ( in_array( $css_selector, $allowed_attr, true ) ) {
    17951824                                $found = true;
     1825                                $url_attr = in_array( $css_selector, $css_url_data_types, true );
     1826                        }
    17961827                }
    1797                 if ( $found ) {
    1798                         if( $css != '' )
     1828
     1829                if ( $found && $url_attr ) {
     1830                        // Simplified: matches the sequence `url(*)`.
     1831                        preg_match_all( '/url\([^)]+\)/', $parts[1], $url_matches );
     1832
     1833                        foreach ( $url_matches[0] as $url_match ) {
     1834                                // Clean up the URL from each of the matches above.
     1835                                preg_match( '/^url\(\s*([\'\"]?)(.*)(\g1)\s*\)$/', $url_match, $url_pieces );
     1836                                $url = trim( $url_pieces[2] );
     1837
     1838                                if ( empty( $url ) || $url !== wp_kses_bad_protocol( $url ) ) {
     1839                                        $found = false;
     1840                                        break;
     1841                                } else {
     1842                                        // Remove the whole `url(*)` bit that was matched above from the CSS.
     1843                                        $css_test_string = str_replace( $url_match, '', $css_test_string );
     1844                                }
     1845                        }
     1846                }
     1847
     1848                if ( $found && ! preg_match( '%[\\\(&=}]|/\*%', $css_test_string ) ) {
     1849                        if ( $css != '' ) {
    17991850                                $css .= ';';
     1851                        }
     1852
    18001853                        $css .= $css_item;
    18011854                }
    18021855        }