WordPress.org

Make WordPress Core

Ticket #35395: 35395.diff

File 35395.diff, 8.2 KB (added by celloexpressions, 3 years ago)

Add validation for unclosed code comments and unbalanced braces. Also adds a shell sanitization function.

  • src/wp-admin/css/customize-controls.css

     
    534534        margin-bottom: 5px;
    535535}
    536536
     537.customize-control-description a.external-link:after {
     538    font: 16px/11px dashicons;
     539    content: "\f310";
     540    top: 3px;
     541    position: relative;
     542}
     543
    537544.customize-control-color .color-picker,
    538545.customize-control-upload div {
    539546        line-height: 28px;
  • src/wp-includes/class-wp-customize-control.php

     
    446446         *
    447447         * Allows the content to be overriden without having to rewrite the wrapper in `$this::render()`.
    448448         *
    449          * Supports basic input types `text`, `checkbox`, `textarea`, `radio`, `select` and `dropdown-pages`.
     449         * Supports basic input types `none`, `text`, `checkbox`, `textarea`, `radio`, `select` and `dropdown-pages`.
    450450         * Additional input types such as `email`, `url`, `number`, `hidden` and `date` are supported implicitly.
    451451         *
    452452         * Control content can alternately be rendered in JS. See WP_Customize_Control::print_template().
     
    455455         */
    456456        protected function render_content() {
    457457                switch( $this->type ) {
     458                        case 'none':
     459                                        if ( ! empty( $this->label ) ) : ?>
     460                                                <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
     461                                        <?php endif;
     462                                        if ( ! empty( $this->description ) ) : ?>
     463                                                <span class="description customize-control-description"><?php echo $this->description; ?></span>
     464                                        <?php endif;
     465                                break;
    458466                        case 'checkbox':
    459467                                ?>
    460468                                <label>
  • src/wp-includes/class-wp-customize-manager.php

     
    15351535                <script type="text/html" id="tmpl-customize-control-notifications">
    15361536                        <ul>
    15371537                                <# _.each( data.notifications, function( notification ) { #>
    1538                                         <li class="notice notice-{{ notification.type || 'info' }} {{ data.altNotice ? 'notice-alt' : '' }}" data-code="{{ notification.code }}" data-type="{{ notification.type }}">{{ notification.message || notification.code }}</li>
     1538                                        <li class="notice notice-{{ notification.type || 'info' }} {{ data.altNotice ? 'notice-alt' : '' }}" data-code="{{ notification.code }}" data-type="{{ notification.type }}">{{{ notification.message || notification.code }}}</li>
    15391539                                <# } ); #>
    15401540                        </ul>
    15411541                </script>
     
    23152315                                'type'       => 'dropdown-pages',
    23162316                        ) );
    23172317                }
     2318
     2319                /* Custom CSS */
     2320
     2321                $this->add_section( 'custom_css', array(
     2322                        'title'    => __( 'Custom CSS' ),
     2323                        'priority' => 140,
     2324                ) );
     2325
     2326                $this->add_setting( 'wp_custom_css' , array(
     2327                        'type'              => 'theme_mod',
     2328                        'transport'         => 'postMessage',
     2329                        'sanitize_callback' => array( $this, '_sanitize_css' ),
     2330                        'validate_callback' => array( $this, '_validate_css' ),
     2331                ) );
     2332
     2333                $this->add_control( 'wp_custom_css', array(
     2334                        'label'       => __( 'Custom CSS' ),
     2335                        'description' => __( 'CSS allows you to customize the appearance and layout of your site with code. Each theme has its own set of CSS styles, which this option overrides on a per-theme basis. <a href="https://codex.wordpress.org/Know_Your_Sources#CSS" class="external-link" target="_blank">Learn more about CSS <span class="screen-reader-text">(link opens in a new window)</span></a>.' ),
     2336                        'type'        => 'textarea',
     2337                        'section'     => 'custom_css',
     2338                ) );
     2339
     2340                if ( ! is_multisite() ) {
     2341                        $this->add_setting( 'wp_custom_css_more', array() );
     2342                        $this->add_control( 'wp_custom_css_more', array(
     2343                                'type' => 'none',
     2344                                'description' => __( 'Enjoy writing custom CSS? <a href="https://developer.wordpress.org/themes/advanced-topics/child-themes/" class="external-link" target="_blank">Take your customizations to the next level with a child theme <span class="screen-reader-text">(link opens in a new window)</span></a>.' ),
     2345                                'section'     => 'custom_css',
     2346                        ) );
     2347                }
     2348
     2349                $this->selective_refresh->add_partial( 'wp_custom_css', array(
     2350                        'selector' => '#wp-custom-css',
     2351                        'render_callback' => 'wp_get_custom_css',
     2352                ) );
    23182353        }
    23192354
    23202355        /**
     
    23522387        }
    23532388
    23542389        /**
     2390         * Callback for sanitizing CSS.
     2391         *
     2392         * @since 4.7.0
     2393         *
     2394         * @param string $css
     2395         * @return mixed
     2396         */
     2397        public function _sanitize_css( $css ) {
     2398                // @todo determine what is required for CSS sanitization. Likely requires breaking css into arrays and handling piece by piece.
     2399
     2400                return $css;
     2401        }
     2402
     2403        /**
     2404         * Callback for validating CSS.
     2405         *
     2406         * Checks for unbalanced braces and unclosed comments.
     2407         *
     2408         * @since 4.7.0
     2409         *
     2410         * @param mixed  $validity
     2411         * @param string $css
     2412         * @return mixed
     2413         */
     2414        public function _validate_css( $validity, $css ) {
     2415                // Make sure that there is a closing brace for each opening brace.
     2416                if ( substr_count( $css, '{' ) !== substr_count( $css, '}' ) ) {
     2417                        $validity->add( 'unbalanced_braces', __( 'Your braces <code>{}</code> are unbalanced. Make sure there is a closing <code>}</code> for every opening <code>{</code>.' ) );
     2418                }
     2419               
     2420                // Make sure that any code comments are closed properly.
     2421                $count = 0;
     2422                $comments = explode( '/*', $css );
     2423                unset( $comments[0] ); // The first array came before the first comment.
     2424                foreach( $comments as $comment ) {
     2425                        if ( false === strpos( $comment, '*/' ) ) {
     2426                                $count++;
     2427                        }
     2428                }
     2429                if ( 0 < $count ) {
     2430                        $validity->add( 'unclosed_comment', sprintf( _n( 'There is an unclosed code comment. Close each comment with <code>*/</code>.', 'There are %s unclosed code comments. Close each comment with <code>*/</code>.', $count ), $count ) );
     2431                }
     2432
     2433                return $validity;
     2434        }
     2435
     2436        /**
    23552437         * Callback for rendering the custom logo, used in the custom_logo partial.
    23562438         *
    23572439         * This method exists because the partial object and context data are passed
  • src/wp-includes/default-filters.php

     
    244244add_action( 'wp_head',             'wp_generator'                           );
    245245add_action( 'wp_head',             'rel_canonical'                          );
    246246add_action( 'wp_head',             'wp_shortlink_wp_head',            10, 0 );
     247add_action( 'wp_head',             'wp_custom_css_cb',                11    );
    247248add_action( 'wp_head',             'wp_site_icon',                    99    );
    248249add_action( 'wp_footer',           'wp_print_footer_scripts',         20    );
    249250add_action( 'template_redirect',   'wp_shortlink_header',             11, 0 );
  • src/wp-includes/js/customize-preview.js

     
    235235                        $( 'body' ).toggleClass( 'wp-custom-logo', !! setting.get() );
    236236                        setting.bind( function( attachmentId ) {
    237237                                $( 'body' ).toggleClass( 'wp-custom-logo', !! attachmentId );
     238                        });
     239                });
     240
     241                api( 'wp_custom_css', function( value ) {
     242                        value.bind( function( to ) {
     243                                $( '#wp-custom-css' ).html( to );
    238244                        } );
    239245                } );
    240246
  • src/wp-includes/theme.php

     
    14001400<?php
    14011401}
    14021402
     1403
    14031404/**
     1405 * Render custom CSS.
     1406 *
     1407 * @since 4.7.0
     1408 */
     1409function wp_custom_css_cb() {
     1410        $styles = get_theme_mod( 'wp_custom_css' );
     1411        if ( $styles ) :
     1412?>
     1413        <style type="text/css" id="wp-custom-css">
     1414                <?php echo $styles; ?>
     1415        </style>
     1416<?php
     1417        endif;
     1418}
     1419
     1420/**
     1421 * Get custom CSS.
     1422 *
     1423 * @return string CSS.
     1424 * @since 4.7.0
     1425 */
     1426function wp_get_custom_css() {
     1427        return get_theme_mod( 'wp_custom_css', '' );
     1428}
     1429
     1430/**
    14041431 * Add callback for custom TinyMCE editor stylesheets.
    14051432 *
    14061433 * The parameter $stylesheet is the name of the stylesheet, relative to