From 472a436111dc9b9c10b9be45cd30e6447957ef5a Mon Sep 17 00:00:00 2001 From: "Soare Robert Daniel (Mac 2023)" Date: Mon, 15 Apr 2024 11:08:06 +0300 Subject: [PATCH 1/3] fix(posts): `titleTag` sanitization --- inc/render/class-posts-grid-block.php | 25 ++++++++++++++----- tests/test-post-grid-block.php | 35 ++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/inc/render/class-posts-grid-block.php b/inc/render/class-posts-grid-block.php index e6b2eacd0..773548438 100644 --- a/inc/render/class-posts-grid-block.php +++ b/inc/render/class-posts-grid-block.php @@ -153,12 +153,7 @@ public function get_post_fields( $id, $attributes ) { if ( 'title' === $element ) { if ( isset( $attributes['displayTitle'] ) && $attributes['displayTitle'] ) { - $html .= sprintf( - '<%1$s class="o-posts-grid-post-title">%3$s', - esc_attr( $attributes['titleTag'] ), - esc_url( get_the_permalink( $id ) ), - esc_html( get_the_title( $id ) ) - ); + $html .= $this->render_post_title( $attributes['titleTag'], get_the_permalink( $id ), get_the_title( $id ) ); } } @@ -410,4 +405,22 @@ protected function render_pagination( $page_number, $total_pages ) { return $output; } + + /** + * Render the post title. + * + * @param string $tag The html tag. + * @param string $post_url The post URL. + * @param string $post_title The post title. + * + * @return string The rendered post title. + */ + public function render_post_title( $tag, $post_url, $post_title ) { + return sprintf( + '<%1$s class="o-posts-grid-post-title">%3$s', + sanitize_key( $tag ), + esc_url( $post_url ), + esc_html( $post_title ) + ); + } } diff --git a/tests/test-post-grid-block.php b/tests/test-post-grid-block.php index abfacf204..31b50d99e 100644 --- a/tests/test-post-grid-block.php +++ b/tests/test-post-grid-block.php @@ -77,26 +77,53 @@ class Test_Post_Grid_Block extends WP_UnitTestCase { ); /** - * Test the fetching of patterns. + * Test the rendering of the block. */ - public function test_render_sanitization() { + public function test_render() { $this->post_grid_block = new Posts_Grid_Block(); WP_Block_Supports::init(); WP_Block_Supports::$block_to_render = array( 'blockName' => 'themeisle-blocks/posts-grid' ); - $base_attributes = $this->attributes; + $base_attributes = unserialize(serialize($this->attributes)); $output = $this->post_grid_block->render( $base_attributes ); $expected = '
'; $this->assertEquals( $expected, $output ); + } + + /** + * Test the rendering of the item post title. + */ + public function test_render_post_title() { + $this->post_grid_block = new Posts_Grid_Block(); + + $output = $this->post_grid_block->render_post_title( 'h5', 'www.example.com', 'Title' ); + $expected = '
Title
'; + $this->assertEquals( $expected, $output ); + } - $malformed_attributes = $base_attributes; + /** + * Test render sanitization. + */ + public function test_render_sanitization() { + $this->post_grid_block = new Posts_Grid_Block(); + WP_Block_Supports::init(); + WP_Block_Supports::$block_to_render = array( 'blockName' => 'themeisle-blocks/posts-grid' ); + + $malformed_attributes = unserialize(serialize($this->attributes)); $malformed_attributes['id'] = 'wp-block-themeisle-blocks-posts-grid-12345\\"onmouseover=alert(123) b='; + $malformed_attributes['titleTag'] = 'h5 onmouseover=alert(456)'; // We expect the id to be sanitized. $expected = '
'; $output = $this->post_grid_block->render( $malformed_attributes ); $this->assertEquals( $expected, $output ); + + // We expect the titleTag to be sanitized. + $expected = 'Title'; + $output = $this->post_grid_block->render_post_title( $malformed_attributes['titleTag'], 'www.example.com', 'Title' ); + + $this->assertEquals( $expected, $output ); } } From a1067424a24b6d424d7d6fac361731d5556fb936 Mon Sep 17 00:00:00 2001 From: "Soare Robert Daniel (Mac 2023)" Date: Mon, 15 Apr 2024 12:14:18 +0300 Subject: [PATCH 2/3] fix(posts): constrain rendering choices for `titleTag` --- inc/render/class-posts-grid-block.php | 9 ++++++++- tests/test-post-grid-block.php | 8 ++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/inc/render/class-posts-grid-block.php b/inc/render/class-posts-grid-block.php index 773548438..94ae3730e 100644 --- a/inc/render/class-posts-grid-block.php +++ b/inc/render/class-posts-grid-block.php @@ -416,9 +416,16 @@ protected function render_pagination( $page_number, $total_pages ) { * @return string The rendered post title. */ public function render_post_title( $tag, $post_url, $post_title ) { + + $tag = sanitize_key( $tag ); + + if ( ! in_array( $tag, array( 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ), true ) ) { + $tag = 'h5'; + } + return sprintf( '<%1$s class="o-posts-grid-post-title">%3$s', - sanitize_key( $tag ), + $tag, esc_url( $post_url ), esc_html( $post_title ) ); diff --git a/tests/test-post-grid-block.php b/tests/test-post-grid-block.php index 31b50d99e..b49eef8f7 100644 --- a/tests/test-post-grid-block.php +++ b/tests/test-post-grid-block.php @@ -97,8 +97,8 @@ public function test_render() { public function test_render_post_title() { $this->post_grid_block = new Posts_Grid_Block(); - $output = $this->post_grid_block->render_post_title( 'h5', 'www.example.com', 'Title' ); - $expected = '
Title
'; + $output = $this->post_grid_block->render_post_title( 'h3', 'www.example.com', 'Title' ); + $expected = '

Title

'; $this->assertEquals( $expected, $output ); } @@ -112,7 +112,7 @@ public function test_render_sanitization() { $malformed_attributes = unserialize(serialize($this->attributes)); $malformed_attributes['id'] = 'wp-block-themeisle-blocks-posts-grid-12345\\"onmouseover=alert(123) b='; - $malformed_attributes['titleTag'] = 'h5 onmouseover=alert(456)'; + $malformed_attributes['titleTag'] = 'h3 onmouseover=alert(456)'; // We expect the id to be sanitized. $expected = '
'; @@ -121,7 +121,7 @@ public function test_render_sanitization() { $this->assertEquals( $expected, $output ); // We expect the titleTag to be sanitized. - $expected = 'Title'; + $expected = '
Title
'; $output = $this->post_grid_block->render_post_title( $malformed_attributes['titleTag'], 'www.example.com', 'Title' ); $this->assertEquals( $expected, $output ); From 0c514e641a1f3bd85e3e41488a08d20420c4f217 Mon Sep 17 00:00:00 2001 From: "Soare Robert Daniel (Mac 2023)" Date: Mon, 15 Apr 2024 12:28:02 +0300 Subject: [PATCH 3/3] fix(posts): check `titleTag` value in block editor preview --- .../blocks/posts/components/layout/index.js | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/blocks/blocks/posts/components/layout/index.js b/src/blocks/blocks/posts/components/layout/index.js index b3352dce8..09723661c 100644 --- a/src/blocks/blocks/posts/components/layout/index.js +++ b/src/blocks/blocks/posts/components/layout/index.js @@ -110,17 +110,20 @@ export const PostsCategory = ({ attributes, element, category, categoriesList }) }; export const PostsTitle = ({ attributes, element, post }) => { - const Tag = attributes.titleTag || 'h5'; - if ( attributes.displayTitle ) { - return ( - - - { unescapeHTML( post.title?.rendered ) } - - - ); + + if ( ! attributes.displayTitle ) { + return ''; } - return ''; + + const Tag = ! [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ].includes( attributes.titleTag ) ? 'h5' : attributes.titleTag; + + return ( + + + { unescapeHTML( post.title?.rendered ) } + + + ); }; export const PostsMeta = ({ attributes, element, post, author, categories }) => {