Changeset 61486 for trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php
- Timestamp:
- 01/15/2026 12:08:01 PM (3 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php
r61429 r61486 276 276 $config['isGlobalStylesUserThemeJSON'] = true; 277 277 $config['version'] = WP_Theme_JSON::LATEST_SCHEMA; 278 $changes->post_content = wp_json_encode( $config ); 278 /** 279 * JSON encode the data stored in post content. 280 * Escape characters that are likely to be mangled by HTML filters: "<>&". 281 * 282 * This data is later re-encoded by {@see wp_filter_global_styles_post()}. 283 * The escaping is also applied here as a precaution. 284 */ 285 $changes->post_content = wp_json_encode( $config, JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ); 279 286 } 280 287 … … 660 667 * Validate style.css as valid CSS. 661 668 * 662 * Currently just checks for invalid markup.669 * Currently just checks that CSS will not break an HTML STYLE tag. 663 670 * 664 671 * @since 6.2.0 665 672 * @since 6.4.0 Changed method visibility to protected. 673 * @since 7.0.0 Only restricts contents which risk prematurely closing the STYLE element, 674 * either through a STYLE end tag or a prefix of one which might become a 675 * full end tag when combined with the contents of other styles. 666 676 * 667 677 * @param string $css CSS to validate. … … 669 679 */ 670 680 protected function validate_custom_css( $css ) { 671 if ( preg_match( '#</?\w+#', $css ) ) { 672 return new WP_Error( 673 'rest_custom_css_illegal_markup', 674 __( 'Markup is not allowed in CSS.' ), 675 array( 'status' => 400 ) 681 $length = strlen( $css ); 682 for ( 683 $at = strcspn( $css, '<' ); 684 $at < $length; 685 $at += strcspn( $css, '<', ++$at ) 686 ) { 687 $remaining_strlen = $length - $at; 688 /** 689 * Custom CSS text is expected to render inside an HTML STYLE element. 690 * A STYLE closing tag must not appear within the CSS text because it 691 * would close the element prematurely. 692 * 693 * The text must also *not* end with a partial closing tag (e.g., `<`, 694 * `</`, … `</style`) because subsequent styles which are concatenated 695 * could complete it, forming a valid `</style>` tag. 696 * 697 * Example: 698 * 699 * $style_a = 'p { font-weight: bold; </sty'; 700 * $style_b = 'le> gotcha!'; 701 * $combined = "{$style_a}{$style_b}"; 702 * 703 * $style_a = 'p { font-weight: bold; </style'; 704 * $style_b = 'p > b { color: red; }'; 705 * $combined = "{$style_a}\n{$style_b}"; 706 * 707 * Note how in the second example, both of the style contents are benign 708 * when analyzed on their own. The first style was likely the result of 709 * improper truncation, while the second is perfectly sound. It was only 710 * through concatenation that these two scripts combined to form content 711 * that would have broken out of the containing STYLE element, thus 712 * corrupting the page and potentially introducing security issues. 713 * 714 * @see https://html.spec.whatwg.org/multipage/parsing.html#rawtext-end-tag-name-state 715 */ 716 $possible_style_close_tag = 0 === substr_compare( 717 $css, 718 '</style', 719 $at, 720 min( 7, $remaining_strlen ), 721 true 676 722 ); 677 } 723 if ( $possible_style_close_tag ) { 724 if ( $remaining_strlen < 8 ) { 725 return new WP_Error( 726 'rest_custom_css_illegal_markup', 727 sprintf( 728 /* translators: %s is the CSS that was provided. */ 729 __( 'The CSS must not end in "%s".' ), 730 esc_html( substr( $css, $at ) ) 731 ), 732 array( 'status' => 400 ) 733 ); 734 } 735 736 if ( 1 === strspn( $css, " \t\f\r\n/>", $at + 7, 1 ) ) { 737 return new WP_Error( 738 'rest_custom_css_illegal_markup', 739 sprintf( 740 /* translators: %s is the CSS that was provided. */ 741 __( 'The CSS must not contain "%s".' ), 742 esc_html( substr( $css, $at, 8 ) ) 743 ), 744 array( 'status' => 400 ) 745 ); 746 } 747 } 748 } 749 678 750 return true; 679 751 }
Note: See TracChangeset
for help on using the changeset viewer.