Skip to content

Commit 612e80e

Browse files
committed
comments: allow img tags when editing comments in admin.
1 parent ac186d7 commit 612e80e

2 files changed

Lines changed: 100 additions & 0 deletions

File tree

src/wp-includes/comment.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2635,6 +2635,30 @@ function wp_update_comment( $commentarr, $wp_error = false ) {
26352635
$filter_comment = ! user_can( $comment['user_id'] ?? 0, 'unfiltered_html' );
26362636
}
26372637

2638+
// Allow images in comments when edited by users with appropriate capabilities in admin.
2639+
$img_filter_callback = null;
2640+
if ( is_admin() && current_user_can( 'edit_comment', $commentarr['comment_ID'] ) ) {
2641+
$img_filter_callback = function ( $allowed_html ) {
2642+
if ( ! isset( $allowed_html['img'] ) ) {
2643+
$allowed_html['img'] = array(
2644+
'alt' => true,
2645+
'align' => true,
2646+
'border' => true,
2647+
'height' => true,
2648+
'hspace' => true,
2649+
'loading' => true,
2650+
'longdesc' => true,
2651+
'vspace' => true,
2652+
'src' => true,
2653+
'usemap' => true,
2654+
'width' => true,
2655+
);
2656+
}
2657+
return $allowed_html;
2658+
};
2659+
add_filter( 'wp_kses_allowed_html', $img_filter_callback );
2660+
}
2661+
26382662
if ( $filter_comment ) {
26392663
add_filter( 'pre_comment_content', 'wp_filter_kses' );
26402664
}
@@ -2653,6 +2677,10 @@ function wp_update_comment( $commentarr, $wp_error = false ) {
26532677
remove_filter( 'pre_comment_content', 'wp_filter_kses' );
26542678
}
26552679

2680+
if ( $img_filter_callback ) {
2681+
remove_filter( 'wp_kses_allowed_html', $img_filter_callback );
2682+
}
2683+
26562684
// Now extract the merged array.
26572685
$data = wp_unslash( $commentarr );
26582686

tests/phpunit/tests/comment.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,78 @@ public function test_update_comment_from_unprivileged_user_by_privileged_user()
176176
);
177177
}
178178

179+
/**
180+
* @ticket 57979
181+
*
182+
* @covers ::wp_update_comment
183+
*/
184+
public function test_update_comment_allows_images_in_admin_by_privileged_user() {
185+
wp_set_current_user( self::$user_id );
186+
187+
$comment_id = wp_new_comment(
188+
array(
189+
'comment_post_ID' => self::$post_id,
190+
'comment_author' => 'Author',
191+
'comment_author_url' => 'http://example.localhost/',
192+
'comment_author_email' => 'author@example.com',
193+
'user_id' => self::$user_id,
194+
'comment_content' => '<a href="http://example.localhost/something.html">click</a>',
195+
)
196+
);
197+
198+
wp_set_current_user( 0 );
199+
200+
$admin_id = self::factory()->user->create(
201+
array(
202+
'role' => 'administrator',
203+
'user_login' => 'test_wp_admin_get',
204+
'user_pass' => 'password',
205+
'user_email' => 'testadmin@example.com',
206+
)
207+
);
208+
209+
wp_set_current_user( $admin_id );
210+
211+
// Simulate admin context.
212+
set_current_screen( 'edit-comments' );
213+
214+
wp_update_comment(
215+
array(
216+
'comment_ID' => $comment_id,
217+
'comment_content' => '<img src="http://example.localhost/image.jpg" alt="Test image" width="100" height="50">',
218+
)
219+
);
220+
221+
// Reset current screen.
222+
set_current_screen( 'front' );
223+
224+
wp_set_current_user( 0 );
225+
226+
$comment = get_comment( $comment_id );
227+
$this->assertStringContainsString( '<img', $comment->comment_content );
228+
$this->assertStringContainsString( 'src="http://example.localhost/image.jpg"', $comment->comment_content );
229+
$this->assertStringContainsString( 'alt="Test image"', $comment->comment_content );
230+
231+
// Verify that malicious attributes are still stripped by KSES.
232+
wp_set_current_user( $admin_id );
233+
set_current_screen( 'edit-comments' );
234+
235+
wp_update_comment(
236+
array(
237+
'comment_ID' => $comment_id,
238+
'comment_content' => '<img src="x.jpg" onerror="alert(1)">',
239+
)
240+
);
241+
242+
set_current_screen( 'front' );
243+
wp_set_current_user( 0 );
244+
245+
$comment = get_comment( $comment_id );
246+
$this->assertStringContainsString( '<img', $comment->comment_content );
247+
$this->assertStringNotContainsString( 'onerror', $comment->comment_content );
248+
$this->assertStringNotContainsString( 'alert', $comment->comment_content );
249+
}
250+
179251
/**
180252
* @ticket 30627
181253
*

0 commit comments

Comments
 (0)