Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add additional sanitization for settings.typography.fontFamilies #53273

Closed
wants to merge 10 commits into from
72 changes: 64 additions & 8 deletions lib/class-wp-theme-json-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,30 @@
'fluid' => null,
'customFontSize' => null,
'dropCap' => null,
'fontFamilies' => null,
'fontFamilies' => array(
array(
'name' => null,
'slug' => null,
'fontFamily' => null,
'fontFace' => array(
array(
'ascentOverride' => null,
'descentOverride' => null,
'fontDisplay' => null,
'fontFamily' => null,
'fontFeatureSettings' => null,
'fontStyle' => null,
'fontStretch' => null,
'fontVariationSettings' => null,
'fontWeight' => null,
'lineGapOverride' => null,
'sizeAdjust' => null,
'src' => null,
'unicodeRange' => null,
),
),
),
),
'fontSizes' => null,
'fontStyle' => null,
'fontWeight' => null,
Expand Down Expand Up @@ -701,7 +724,7 @@

unset( $context['appearanceTools'] );
}

Check failure on line 727 in lib/class-wp-theme-json-gutenberg.php

View workflow job for this annotation

GitHub Actions / PHP coding standards

Whitespace found at end of line
/**
* Sanitizes the input according to the schemas.
*
Expand Down Expand Up @@ -796,6 +819,35 @@
$schema['settings'] = static::VALID_SETTINGS;
$schema['settings']['blocks'] = $schema_settings_blocks;

// For settings.typography.fontFamilies, make the $schema have all indexes present in the $input.
if ( isset( $input['settings']['typography']['fontFamilies'] ) ) {
// Do not handle the cases where the sanitization is called before font families are merged, since it will be handled again later.
if ( ! isset( $input['settings']['typography']['fontFamilies']['theme'] ) || ! isset( $input['settings']['typography']['fontFamilies']['custom'] ) ) {
foreach ( $input['settings']['typography']['fontFamilies'] as $font_family_key => $value ) {
$schema['settings']['typography']['fontFamilies'][ $font_family_key ] = static::VALID_SETTINGS['typography']['fontFamilies'][0];
// Do the same for fontFace.
if ( isset( $input['settings']['typography']['fontFamilies'][ $font_family_key ]['fontFace'] ) ) {
foreach ( $input['settings']['typography']['fontFamilies'][ $font_family_key ]['fontFace'] as $font_face_key => $value2 ) {
$schema['settings']['typography']['fontFamilies'][ $font_family_key ]['fontFace'][ $font_face_key ] = static::VALID_SETTINGS['typography']['fontFamilies'][0]['fontFace'][0];
}
}
}
} else {
foreach ( $input['settings']['typography']['fontFamilies']['theme'] as $font_family_key => $value ) {
$schema['settings']['typography']['fontFamilies']['theme'][ $font_family_key ] = static::VALID_SETTINGS['typography']['fontFamilies'][0];
// Do the same for fontFace.
if ( isset( $input['settings']['typography']['fontFamilies']['theme'][ $font_family_key ]['fontFace'] ) ) {
foreach ( $input['settings']['typography']['fontFamilies']['theme'][ $font_family_key ]['fontFace'] as $font_face_key => $value2 ) {
$schema['settings']['typography']['fontFamilies']['theme'][ $font_family_key ]['fontFace'][ $font_face_key ] = static::VALID_SETTINGS['typography']['fontFamilies'][0]['fontFace'][0];
}
}
}
if ( array_key_exists( 0, $schema['settings']['typography']['fontFamilies'] ) ) {
unset( $schema['settings']['typography']['fontFamilies'][0] );
}
}
}

// Remove anything that's not present in the schema.
foreach ( array( 'styles', 'settings' ) as $subtree ) {
if ( ! isset( $input[ $subtree ] ) ) {
Expand Down Expand Up @@ -3278,16 +3330,20 @@
$items = array();
if ( isset( $preset['theme'] ) ) {
foreach ( $preset['theme'] as $item ) {
$slug = $item['slug'];
unset( $item['slug'] );
$items[ $slug ] = $item;
if ( is_array( $item ) ) {
$slug = $item['slug'];
unset( $item['slug'] );
$items[ $slug ] = $item;
}
}
}
if ( isset( $preset['custom'] ) ) {
foreach ( $preset['custom'] as $item ) {
$slug = $item['slug'];
unset( $item['slug'] );
$items[ $slug ] = $item;
if ( is_array( $item ) ) {
$slug = $item['slug'];
unset( $item['slug'] );
$items[ $slug ] = $item;
}
}
}
$flattened_preset = array();
Expand Down
84 changes: 84 additions & 0 deletions phpunit/class-wp-theme-json-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,90 @@ public function test_remove_invalid_element_pseudo_selectors() {
$this->assertEqualSetsWithIndex( $expected, $actual );
}

public function test_sanitize_invalid_typography_settings() {
$theme_json = new WP_Theme_JSON_Gutenberg(
array(
'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA,
'settings' => array(
'typography' => array(
'fontFamilies' => array(
'badKey' => 'I am invalid',
'theme' => array(
'name' => 'Inter',
'slug' => 'inter',
'badKey' => 'I am invalid',
'fontFamily' => 'Inter',
'fontFace' => array(
array(
'anotherKey' => 'I am invalid',
'fontFamily' => 'Inter',
'fontStyle' => 'normal',
'fontWeight' => '400',
'src' => 'https://example.com/inter.ttf',
),
),
),
array(
'name' => 'Piazzolla',
'slug' => 'piazzolla',
'badKey' => 'I am invalid',
'fontFamily' => 'Piazzolla',
'fontFace' => array(
array(
'anotherKey' => 'I am invalid',
'fontFamily' => 'Piazzolla',
'fontStyle' => 'italic',
'fontWeight' => '400',
'src' => 'https://example.com/font.ttf',
),
),
),
),
'src' => 'https://example.com/font.ttf',
),
),
)
);

$sanitized_theme_json = $theme_json->get_data();
$expected = array(
'version' => 2,
'settings' => array(
'typography' => array(
'fontFamilies' => array(
array(
'fontFace' => array(
array(
'fontFamily' => 'Inter',
'fontStyle' => 'normal',
'fontWeight' => '400',
'src' => 'https://example.com/inter.ttf',
),
),
'fontFamily' => 'Inter',
'name' => 'Inter',
'slug' => 'inter',
),
array(
'fontFace' => array(
array(
'fontFamily' => 'Piazzolla',
'fontStyle' => 'italic',
'fontWeight' => '400',
'src' => 'https://example.com/font.ttf',
),
),
'fontFamily' => 'Piazzolla',
'name' => 'Piazzolla',
'slug' => 'piazzolla',
),
),
),
),
);
$this->assertSameSetsWithIndex( $expected, $sanitized_theme_json, 'Sanitized theme.json settings do not match.' );
}

public function test_get_element_class_name_button() {
$expected = 'wp-element-button';
$actual = WP_Theme_JSON_Gutenberg::get_element_class_name( 'button' );
Expand Down
Loading