Skip to content

Commit 67eeb94

Browse files
release: fixes
- Fixed issue of HTML code appearing on the front-end by allowing partial HTML tag rendering for Multiple Choice Label - Fix fatal crash in Block Conditions when rendering condition is set to `false` - Fixed issue with multiple instances of Pattern Upsell appearing on the same page - Updated internal dependencies
2 parents 2d85140 + 5f7bd3e commit 67eeb94

File tree

7 files changed

+135
-23
lines changed

7 files changed

+135
-23
lines changed

composer.lock

+12-16
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

inc/plugins/class-block-conditions.php

+5-3
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class Block_Conditions {
2626
*/
2727
public function init() {
2828
if ( get_option( 'themeisle_blocks_settings_block_conditions', true ) ) {
29-
add_action( 'render_block', array( $this, 'render_blocks' ), 999, 2 );
29+
add_filter( 'render_block', array( $this, 'render_blocks' ), 999, 2 );
3030
add_action( 'wp_loaded', array( $this, 'add_attributes_to_blocks' ), 999 );
3131
}
3232
}
@@ -36,6 +36,8 @@ public function init() {
3636
*
3737
* @param string $block_content Content of block.
3838
* @param array $block Block Attributes.
39+
*
40+
* @return string
3941
*
4042
* @since 1.7.0
4143
* @access public
@@ -46,12 +48,12 @@ public function render_blocks( $block_content, $block ) {
4648
$display = $this->evaluate_condition_collection( $block['attrs']['otterConditions'] );
4749

4850
if ( false === $display ) {
49-
return;
51+
return '';
5052
}
5153

5254
$enhanced_content = $this->should_add_hide_css_class( $this->get_hide_css_condition( $block['attrs']['otterConditions'] ), $block_content );
5355

54-
if ( false !== $enhanced_content ) {
56+
if ( false !== $enhanced_content && is_string( $enhanced_content ) ) {
5557
return $enhanced_content;
5658
}
5759
}

inc/render/class-form-multiple-choice.php

+22-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,28 @@ public function render_field( $type, $label, $value, $name, $id, $checked = fals
8989
$output = '<div class="o-form-multiple-choice-field">';
9090

9191
$output .= '<input type="' . esc_attr( $type ) . '" name="' . esc_attr( $name ) . '" id="' . esc_attr( $id ) . '" value="' . esc_attr( $value ) . '" ' . ( $is_required ? 'required' : '' ) . ( $checked ? ' checked' : '' ) . ' />';
92-
$output .= '<label for="' . esc_attr( $id ) . '" class="o-form-choice-label">' . esc_html( $label ) . '</label>';
92+
93+
$allowed_tags = array(
94+
'a' => array(
95+
'href' => true,
96+
'target' => true,
97+
),
98+
'img' => array(
99+
'src' => true,
100+
'alt' => true,
101+
'width' => true,
102+
'height' => true,
103+
),
104+
'span' => array(),
105+
'em' => array(),
106+
'strong' => array(),
107+
'i' => array(),
108+
'b' => array(),
109+
);
110+
111+
$label = wp_kses( $label, $allowed_tags );
112+
113+
$output .= '<label for="' . esc_attr( $id ) . '" class="o-form-choice-label">' . $label . '</label>';
93114

94115
$output .= '</div>';
95116

src/blocks/plugins/upsell-block/index.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ const MONTH_IN_MS = 60 * 60 * 1000 * 24 * 30;
3030
const edit = props => {
3131
const { removeBlock } = useDispatch( 'core/block-editor' );
3232

33-
const isEditor = null !== document.querySelector( `#o-upsell-${ props.clientId }` );
34-
3533
useEffect( () => {
34+
const isEditor = Boolean( document.querySelector( `#o-upsell-${ props.clientId }` ) );
35+
3636
if ( isEditor && undefined === window.themeisleGutenberg.hasPatternUpsell ) {
3737
window.themeisleGutenberg.hasPatternUpsell = props.clientId;
3838
}
@@ -50,7 +50,7 @@ const edit = props => {
5050
removeBlock( props.clientId );
5151
}
5252
}
53-
}, [ isEditor ]);
53+
}, []);
5454

5555
return (
5656
<div
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* WordPress dependencies
3+
*/
4+
import { test, expect } from '@wordpress/e2e-test-utils-playwright';
5+
import { tryLoginIn } from '../utils';
6+
7+
test.describe( 'Block Conditions', () => {
8+
test.beforeEach( async({ admin, requestUtils, page }) => {
9+
await tryLoginIn( page, 'admin', 'password' );
10+
await admin.createNewPost();
11+
});
12+
13+
test.afterEach( async({ page }) => {
14+
15+
/**
16+
* Because some conditions require an user to be logged in, we need to log in the user after each test so that we do not break the next test.
17+
*/
18+
await tryLoginIn( page, 'admin', 'password' );
19+
});
20+
21+
test( 'check logged out users', async({ editor, page, admin, requestUtils }) => {
22+
await editor.insertBlock({
23+
name: 'core/image',
24+
attributes: {
25+
url: 'https://mllj2j8xvfl0.i.optimole.com/cb:jC7e.37109/w:794/h:397/q:mauto/dpr:2.0/f:best/https://themeisle.com/blog/wp-content/uploads/2021/01/How-to-Change-Font-in-WordPress-Theme.png',
26+
otterConditions: [
27+
[
28+
{
29+
type: 'loggedInUser'
30+
}
31+
]
32+
]
33+
}
34+
});
35+
36+
const postId = await editor.publishPost();
37+
38+
// Check the block for logged in users.
39+
await page.goto( `/?p=${postId}` );
40+
await expect( page.locator( '#wp--skip-link--target img' ) ).toBeVisible();
41+
42+
// Check the block for logged out users.
43+
await page.getByRole( 'menuitem', { name: 'Howdy, admin' }).hover();
44+
await page.waitForTimeout( 200 );
45+
await page.getByRole( 'menuitem', { name: 'Log Out' }).click();
46+
await page.goto( `/?p=${postId}` );
47+
await expect( page.locator( '#wp--skip-link--target img' ) ).toBeHidden();
48+
});
49+
});

src/blocks/test/e2e/utils.js

+7
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,10 @@ export function deleteFile( filePath ) {
6868
unlinkSync( filePath );
6969
}
7070
}
71+
72+
export async function tryLoginIn( page, username, password ) {
73+
await page.goto( '/wp-login.php' );
74+
await page.fill( 'input[name="log"]', username );
75+
await page.fill( 'input[name="pwd"]', password );
76+
await page.click( 'input[name="wp-submit"]' );
77+
}

tests/test-choices-field-block.php

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
/**
3+
* Test Multiple Choice Field Block.
4+
*
5+
* @package otter-blocks
6+
*/
7+
8+
use ThemeIsle\GutenbergBlocks\Render\Form_Multiple_Choice_Block;
9+
10+
/**
11+
* Class Test Multiple Choices Block
12+
*/
13+
class Test_Multiple_Choices_Block extends WP_UnitTestCase {
14+
15+
public function test_label_sanitization_render() {
16+
$block_render = new Form_Multiple_Choice_Block();
17+
18+
$expected = '<div class="o-form-multiple-choice-field">';
19+
$expected .= '<input type="checkbox" name="otter-blocks" id="otter-blocks" value="otter-blocks" />';
20+
$expected .= '<label for="otter-blocks" class="o-form-choice-label">Option with <a href="www.example.com">link</a></label>';
21+
$expected .= '</div>';
22+
23+
$output = $block_render->render_field( 'checkbox', 'Option with <a href="www.example.com">link</a>', 'otter-blocks', 'otter-blocks', 'otter-blocks' );
24+
25+
$this->assertEquals( $expected, $output );
26+
27+
$malicious_label = 'Option with <a href="www.example.com">link</a><script></script>';
28+
$output = $block_render->render_field( 'checkbox', $malicious_label, 'otter-blocks', 'otter-blocks', 'otter-blocks' );
29+
30+
$this->assertEquals( $expected, $output );
31+
32+
$malicious_label = 'Option with <a href="www.example.com" onclick="alert(123)">link</a>';
33+
$output = $block_render->render_field( 'checkbox', $malicious_label, 'otter-blocks', 'otter-blocks', 'otter-blocks' );
34+
35+
$this->assertEquals( $expected, $output );
36+
}
37+
}

0 commit comments

Comments
 (0)