Skip to content

Commit

Permalink
Update escaping function (#683)
Browse files Browse the repository at this point in the history
* Update escaping function

* update tests

* add method specific for attributes

* update tests

* Updates to only use wp_kses_post when strings contain html

* remove wp_kses_post as escaping function

* update tests

---------

Co-authored-by: Grant Kinney <[email protected]>
  • Loading branch information
matiasbenedetto and creativecoder authored Sep 3, 2024
1 parent bbe5ca5 commit 6973cf8
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 72 deletions.
40 changes: 36 additions & 4 deletions includes/create-theme/theme-locale.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,58 @@
class CBT_Theme_Locale {

/**
* Escape a string for localization.
* Escape text for localization.
*
* @param string $string The string to escape.
* @return string The escaped string.
*/
public static function escape_string( $string ) {
private static function escape_text_content( $string ) {
// Avoid escaping if the text is not a string.
if ( ! is_string( $string ) ) {
return $string;
}

// Check if string is empty.
if ( '' === $string ) {
return $string;
}

// Check if the text is already escaped.
if ( str_starts_with( $string, '<?php' ) ) {
return $string;
}

$string = addcslashes( $string, "'" );

return "<?php esc_html_e('" . $string . "', '" . wp_get_theme()->get( 'TextDomain' ) . "');?>";
}

/**
* Escape an html element attribute for localization.
*
* @param string $string The string to escape.
* @return string The escaped string.
*/
private static function escape_attribute( $string ) {
// Avoid escaping if the text is not a string.
if ( ! is_string( $string ) ) {
return $string;
}

// Check if string is empty.
if ( '' === $string ) {
return $string;
}

// Check if the text is already escaped.
if ( str_starts_with( $string, '<?php' ) ) {
return $string;
}

$string = addcslashes( $string, "'" );
return "<?php esc_attr_e('" . $string . "', '" . wp_get_theme()->get( 'TextDomain' ) . "');?>";
}

/**
* Get a replacement pattern for escaping the text from the html content of a block.
*
Expand Down Expand Up @@ -109,7 +141,7 @@ public static function escape_text_content_of_blocks( $blocks ) {
return preg_replace_callback(
$pattern,
function( $matches ) {
return $matches[1] . self::escape_string( $matches[2] ) . $matches[3];
return $matches[1] . self::escape_text_content( $matches[2] ) . $matches[3];
},
$content
);
Expand All @@ -125,7 +157,7 @@ function( $matches ) {
return preg_replace_callback(
$pattern,
function( $matches ) {
return 'alt="' . self::escape_string( $matches[1] ) . '"';
return 'alt="' . self::escape_attribute( $matches[1] ) . '"';
},
$content
);
Expand Down
2 changes: 1 addition & 1 deletion includes/create-theme/theme-patterns.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public static function escape_alt_for_pattern( $html ) {
public static function escape_text_for_pattern( $text ) {
if ( $text && trim( $text ) !== '' ) {
$escaped_text = addslashes( $text );
return "<?php echo esc_attr_e( '" . $escaped_text . "', '" . wp_get_theme()->get( 'Name' ) . "' ); ?>";
return "<?php esc_attr_e('" . $escaped_text . "', '" . wp_get_theme()->get( 'Name' ) . "');?>";
}
}

Expand Down
58 changes: 58 additions & 0 deletions tests/CbtThemeLocale/escapeAttribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php
require_once __DIR__ . '/base.php';

/**
* Tests for the CBT_Theme_Locale::escape_attribute method.
*
* @package Create_Block_Theme
* @covers CBT_Theme_Locale::escape_attribute
* @group locale
*/
class CBT_Theme_Locale_EscapeAttribute extends CBT_Theme_Locale_UnitTestCase {

protected function call_private_method( $method_name, $args = array() ) {
$reflection = new ReflectionClass( 'CBT_Theme_Locale' );
$method = $reflection->getMethod( $method_name );
$method->setAccessible( true );
return $method->invokeArgs( null, $args );
}

public function test_escape_attribute() {
$string = 'This is a test attribute.';
$escaped_string = $this->call_private_method( 'escape_attribute', array( $string ) );
$expected_string = "<?php esc_attr_e('This is a test attribute.', '" . wp_get_theme()->get( 'TextDomain' ) . "');?>";
$this->assertEquals( $expected_string, $escaped_string );
}

public function test_escape_attribute_with_single_quote() {
$string = "This is a test attribute with a single quote '";
$escaped_string = $this->call_private_method( 'escape_attribute', array( $string ) );
$expected_string = "<?php esc_attr_e('This is a test attribute with a single quote \\'', '" . wp_get_theme()->get( 'TextDomain' ) . "');?>";
$this->assertEquals( $expected_string, $escaped_string );
}

public function test_escape_attribute_with_double_quote() {
$string = 'This is a test attribute with a double quote "';
$escaped_string = $this->call_private_method( 'escape_attribute', array( $string ) );
$expected_string = "<?php esc_attr_e('This is a test attribute with a double quote \"', '" . wp_get_theme()->get( 'TextDomain' ) . "');?>";
$this->assertEquals( $expected_string, $escaped_string );
}

public function test_escape_attribute_with_empty_string() {
$string = '';
$escaped_string = $this->call_private_method( 'escape_attribute', array( $string ) );
$this->assertEquals( $string, $escaped_string );
}

public function test_escape_attribute_with_already_escaped_string() {
$string = "<?php esc_attr_e('This is already escaped.', '" . wp_get_theme()->get( 'TextDomain' ) . "');?>";
$escaped_string = $this->call_private_method( 'escape_attribute', array( $string ) );
$this->assertEquals( $string, $escaped_string );
}

public function test_escape_attribute_with_non_string() {
$string = null;
$escaped_string = $this->call_private_method( 'escape_attribute', array( $string ) );
$this->assertEquals( $string, $escaped_string );
}
}
48 changes: 0 additions & 48 deletions tests/CbtThemeLocale/escapeString.php

This file was deleted.

56 changes: 56 additions & 0 deletions tests/CbtThemeLocale/escapeTextContent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

require_once __DIR__ . '/base.php';

/**
* Tests for the CBT_Theme_Locale::escape_text_content method.
*
* @package Create_Block_Theme
* @covers CBT_Theme_Locale::escape_text_content
* @group locale
*/
class CBT_Theme_Locale_EscapeTextContent extends CBT_Theme_Locale_UnitTestCase {

protected function call_private_method( $method_name, $args = array() ) {
$reflection = new ReflectionClass( 'CBT_Theme_Locale' );
$method = $reflection->getMethod( $method_name );
$method->setAccessible( true );
return $method->invokeArgs( null, $args );
}

public function test_escape_text_content() {
$string = 'This is a test text.';
$escaped_string = $this->call_private_method( 'escape_text_content', array( $string ) );
$this->assertEquals( "<?php esc_html_e('This is a test text.', 'test-locale-theme');?>", $escaped_string );
}

public function test_escape_text_content_with_single_quote() {
$string = "This is a test text with a single quote '";
$escaped_string = $this->call_private_method( 'escape_text_content', array( $string ) );
$this->assertEquals( "<?php esc_html_e('This is a test text with a single quote \\'', 'test-locale-theme');?>", $escaped_string );
}

public function test_escape_text_content_with_double_quote() {
$string = 'This is a test text with a double quote "';
$escaped_string = $this->call_private_method( 'escape_text_content', array( $string ) );
$this->assertEquals( "<?php esc_html_e('This is a test text with a double quote \"', 'test-locale-theme');?>", $escaped_string );
}

public function test_escape_text_content_with_html() {
$string = '<p>This is a test text with HTML.</p>';
$escaped_string = $this->call_private_method( 'escape_text_content', array( $string ) );
$this->assertEquals( "<?php esc_html_e('<p>This is a test text with HTML.</p>', 'test-locale-theme');?>", $escaped_string );
}

public function test_escape_text_content_with_already_escaped_string() {
$string = "<?php esc_html_e('This is a test text.', 'test-locale-theme');?>";
$escaped_string = $this->call_private_method( 'escape_text_content', array( $string ) );
$this->assertEquals( $string, $escaped_string );
}

public function test_escape_text_content_with_non_string() {
$string = null;
$escaped_string = $this->call_private_method( 'escape_text_content', array( $string ) );
$this->assertEquals( $string, $escaped_string );
}
}
10 changes: 3 additions & 7 deletions tests/CbtThemeLocale/escapeTextContentOfBlocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public function data_test_escape_text_content_of_blocks() {
<!-- /wp:image -->',
'expected_markup' =>
'<!-- wp:image {"sizeSlug":"large","linkDestination":"none","className":"is-style-rounded"} -->
<figure class="wp-block-image size-large is-style-rounded"><img src="http://localhost/wp1/wp-content/themes/twentytwentyfour/assets/images/windows.webp" alt="<?php esc_html_e(\'Windows of a building in Nuremberg, Germany\', \'test-locale-theme\');?>"/></figure>
<figure class="wp-block-image size-large is-style-rounded"><img src="http://localhost/wp1/wp-content/themes/twentytwentyfour/assets/images/windows.webp" alt="<?php esc_attr_e(\'Windows of a building in Nuremberg, Germany\', \'test-locale-theme\');?>"/></figure>
<!-- /wp:image -->',
),

Expand All @@ -143,7 +143,7 @@ public function data_test_escape_text_content_of_blocks() {
<!-- /wp:cover -->',
'expected_markup' =>
'<!-- wp:cover {"url":"http://localhost/wp1/wp-content/uploads/2024/05/image.jpeg","id":39,"alt":"Alternative text for cover image","dimRatio":50,"customOverlayColor":"#1d2b2f","layout":{"type":"constrained"}} -->
<div class="wp-block-cover"><span aria-hidden="true" class="wp-block-cover__background has-background-dim" style="background-color:#1d2b2f"></span><img class="wp-block-cover__image-background wp-image-39" alt="<?php esc_html_e(\'Alternative text for cover image\', \'test-locale-theme\');?>" src="http://localhost/wp1/wp-content/uploads/2024/05/image.jpeg" data-object-fit="cover"/><div class="wp-block-cover__inner-container"><!-- wp:paragraph {"align":"center","placeholder":"Write title…","fontSize":"large"} -->
<div class="wp-block-cover"><span aria-hidden="true" class="wp-block-cover__background has-background-dim" style="background-color:#1d2b2f"></span><img class="wp-block-cover__image-background wp-image-39" alt="<?php esc_attr_e(\'Alternative text for cover image\', \'test-locale-theme\');?>" src="http://localhost/wp1/wp-content/uploads/2024/05/image.jpeg" data-object-fit="cover"/><div class="wp-block-cover__inner-container"><!-- wp:paragraph {"align":"center","placeholder":"Write title…","fontSize":"large"} -->
<p class="has-text-align-center has-large-font-size"><?php esc_html_e(\'This is a cover caption\', \'test-locale-theme\');?></p>
<!-- /wp:paragraph --></div></div>
<!-- /wp:cover -->',
Expand All @@ -158,7 +158,7 @@ public function data_test_escape_text_content_of_blocks() {
<!-- /wp:media-text -->',
'expected_markup' =>
'<!-- wp:media-text {"mediaId":39,"mediaLink":"http://localhost/wp1/image/","mediaType":"image"} -->
<div class="wp-block-media-text is-stacked-on-mobile"><figure class="wp-block-media-text__media"><img src="http://localhost/wp1/wp-content/uploads/2024/05/image.jpeg" alt="<?php esc_html_e(\'This is alt text\', \'test-locale-theme\');?>" class="wp-image-39 size-full"/></figure><div class="wp-block-media-text__content"><!-- wp:paragraph {"placeholder":"Content…"} -->
<div class="wp-block-media-text is-stacked-on-mobile"><figure class="wp-block-media-text__media"><img src="http://localhost/wp1/wp-content/uploads/2024/05/image.jpeg" alt="<?php esc_attr_e(\'This is alt text\', \'test-locale-theme\');?>" class="wp-image-39 size-full"/></figure><div class="wp-block-media-text__content"><!-- wp:paragraph {"placeholder":"Content…"} -->
<p><?php esc_html_e(\'Media text content test.\', \'test-locale-theme\');?></p>
<!-- /wp:paragraph --></div></div>
<!-- /wp:media-text -->',
Expand Down Expand Up @@ -189,7 +189,3 @@ public function data_test_escape_text_content_of_blocks() {
);
}
}




Loading

0 comments on commit 6973cf8

Please sign in to comment.