Make WordPress Core


Ignore:
Timestamp:
02/20/2024 07:09:43 AM (10 months ago)
Author:
youknowriad
Message:

Editor: Format and sanitize font family names according the CSS spec.

This fixes two bugs in the font library.

  • Fonts using special characters were not being rendered properly in the frontend.
  • Allows the ability to use generic() in font family names.

Props mmaattiiaass, nithins53, kafleg, vivekawsm, swissspidy, audrasjb.
Fixes #60537.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/fonts/class-wp-font-utils.php

    r57632 r57657  
    2020class WP_Font_Utils {
    2121    /**
     22     * Adds surrounding quotes to font family names that contain special characters.
     23     *
     24     * It follows the recommendations from the CSS Fonts Module Level 4.
     25     * @link https://www.w3.org/TR/css-fonts-4/#font-family-prop
     26     *
     27     * @since 6.5.0
     28     *
     29     * @param string $item A font family name.
     30     * @return string The font family name with surrounding quotes, if necessary.
     31     */
     32    private static function maybe_add_quotes( $item ) {
     33        // Matches strings that are not exclusively alphabetic characters or hyphens, and do not exactly follow the pattern generic(alphabetic characters or hyphens).
     34        $regex = '/^(?!generic\([a-zA-Z\-]+\)$)(?!^[a-zA-Z\-]+$).+/';
     35        $item  = trim( $item );
     36        if ( preg_match( $regex, $item ) ) {
     37            $item = trim( $item, "\"'" );
     38            return '"' . $item . '"';
     39        }
     40        return $item;
     41    }
     42
     43    /**
    2244     * Sanitizes and formats font family names.
    2345     *
    24      * - Applies `sanitize_text_field`
    25      * - Adds surrounding quotes to names that contain spaces and are not already quoted
     46     * - Applies `sanitize_text_field`.
     47     * - Adds surrounding quotes to names containing any characters that are not alphabetic or dashes.
     48     *
     49     * It follows the recommendations from the CSS Fonts Module Level 4.
     50     * @link https://www.w3.org/TR/css-fonts-4/#font-family-prop
    2651     *
    2752     * @since 6.5.0
     
    3863        }
    3964
    40         $font_family           = sanitize_text_field( $font_family );
    41         $font_families         = explode( ',', $font_family );
    42         $wrapped_font_families = array_map(
    43             function ( $family ) {
    44                 $trimmed = trim( $family );
    45                 if ( ! empty( $trimmed ) && str_contains( $trimmed, ' ' ) && ! str_contains( $trimmed, "'" ) && ! str_contains( $trimmed, '"' ) ) {
    46                         return '"' . $trimmed . '"';
     65        $output          = sanitize_text_field( $font_family );
     66        $formatted_items = array();
     67        if ( str_contains( $output, ',' ) ) {
     68            $items = explode( ',', $output );
     69            foreach ( $items as $item ) {
     70                $formatted_item = self::maybe_add_quotes( $item );
     71                if ( ! empty( $formatted_item ) ) {
     72                    $formatted_items[] = $formatted_item;
    4773                }
    48                 return $trimmed;
    49             },
    50             $font_families
    51         );
    52 
    53         if ( count( $wrapped_font_families ) === 1 ) {
    54             $font_family = $wrapped_font_families[0];
    55         } else {
    56             $font_family = implode( ', ', $wrapped_font_families );
    57         }
    58 
    59         return $font_family;
     74            }
     75            return implode( ', ', $formatted_items );
     76        }
     77        return self::maybe_add_quotes( $output );
    6078    }
    6179
Note: See TracChangeset for help on using the changeset viewer.