mirror of
git://develop.git.wordpress.org/
synced 2025-04-08 06:02:41 +02:00
Shortcodes: Restrict ajax handler for media shortcode.
Props tykoted, xknown, peterwilsoncc, antpb, jorbin. Merges [56838] to the 6.3 branch. git-svn-id: https://develop.svn.wordpress.org/branches/6.3@56846 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
9c47921856
commit
82eb50b8af
@ -3882,13 +3882,29 @@ function wp_ajax_parse_media_shortcode() {
|
||||
|
||||
$shortcode = wp_unslash( $_POST['shortcode'] );
|
||||
|
||||
// Only process previews for media related shortcodes:
|
||||
$found_shortcodes = get_shortcode_tags_in_content( $shortcode );
|
||||
$media_shortcodes = array(
|
||||
'audio',
|
||||
'embed',
|
||||
'playlist',
|
||||
'video',
|
||||
'gallery',
|
||||
);
|
||||
|
||||
$other_shortcodes = array_diff( $found_shortcodes, $media_shortcodes );
|
||||
|
||||
if ( ! empty( $other_shortcodes ) ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
if ( ! empty( $_POST['post_ID'] ) ) {
|
||||
$post = get_post( (int) $_POST['post_ID'] );
|
||||
}
|
||||
|
||||
// The embed shortcode requires a post.
|
||||
if ( ! $post || ! current_user_can( 'edit_post', $post->ID ) ) {
|
||||
if ( 'embed' === $shortcode ) {
|
||||
if ( in_array( 'embed', $found_shortcodes, true ) ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
} else {
|
||||
|
@ -2605,6 +2605,7 @@ function gallery_shortcode( $attr ) {
|
||||
$attachments[ $val->ID ] = $_attachments[ $key ];
|
||||
}
|
||||
} elseif ( ! empty( $atts['exclude'] ) ) {
|
||||
$post_parent_id = $id;
|
||||
$attachments = get_children(
|
||||
array(
|
||||
'post_parent' => $id,
|
||||
@ -2617,6 +2618,7 @@ function gallery_shortcode( $attr ) {
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$post_parent_id = $id;
|
||||
$attachments = get_children(
|
||||
array(
|
||||
'post_parent' => $id,
|
||||
@ -2629,6 +2631,17 @@ function gallery_shortcode( $attr ) {
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! empty( $post_parent_id ) ) {
|
||||
$post_parent = get_post( $post_parent_id );
|
||||
|
||||
// terminate the shortcode execution if user cannot read the post or password-protected
|
||||
if (
|
||||
( ! is_post_publicly_viewable( $post_parent->ID ) && ! current_user_can( 'read_post', $post_parent->ID ) )
|
||||
|| post_password_required( $post_parent ) ) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $attachments ) ) {
|
||||
return '';
|
||||
}
|
||||
@ -2961,6 +2974,15 @@ function wp_playlist_shortcode( $attr ) {
|
||||
$attachments = get_children( $args );
|
||||
}
|
||||
|
||||
if ( ! empty( $args['post_parent'] ) ) {
|
||||
$post_parent = get_post( $id );
|
||||
|
||||
// terminate the shortcode execution if user cannot read the post or password-protected
|
||||
if ( ! current_user_can( 'read_post', $post_parent->ID ) || post_password_required( $post_parent ) ) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $attachments ) ) {
|
||||
return '';
|
||||
}
|
||||
|
@ -168,6 +168,44 @@ function has_shortcode( $content, $tag ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of registered shortcode names found in the given content.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* get_shortcode_tags_in_content( '[audio src="file.mp3"][/audio] [foo] [gallery ids="1,2,3"]' );
|
||||
* // array( 'audio', 'gallery' )
|
||||
*
|
||||
* @since 6.3.2
|
||||
*
|
||||
* @param string $content The content to check.
|
||||
* @return string[] An array of registered shortcode names found in the content.
|
||||
*/
|
||||
function get_shortcode_tags_in_content( $content ) {
|
||||
if ( false === strpos( $content, '[' ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
preg_match_all( '/' . get_shortcode_regex() . '/', $content, $matches, PREG_SET_ORDER );
|
||||
if ( empty( $matches ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$tags = array();
|
||||
foreach ( $matches as $shortcode ) {
|
||||
$tags[] = $shortcode[2];
|
||||
|
||||
if ( ! empty( $shortcode[5] ) ) {
|
||||
$deep_tags = get_shortcode_tags_in_content( $shortcode[5] );
|
||||
if ( ! empty( $deep_tags ) ) {
|
||||
$tags = array_merge( $tags, $deep_tags );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches content for shortcodes and filter shortcodes through their hooks.
|
||||
*
|
||||
|
85
tests/phpunit/tests/ajax/wpAjaxParseMediaShortcode.php
Executable file
85
tests/phpunit/tests/ajax/wpAjaxParseMediaShortcode.php
Executable file
@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Admin Ajax functions to be tested.
|
||||
*/
|
||||
require_once ABSPATH . 'wp-admin/includes/ajax-actions.php';
|
||||
|
||||
/**
|
||||
* Testing Ajax save draft functionality.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage UnitTests
|
||||
* @since 6.3.2
|
||||
*
|
||||
* @group ajax
|
||||
*
|
||||
* @covers ::wp_ajax_parse-media-shortcode
|
||||
*/
|
||||
class Tests_Ajax_wpAjaxParseMediaShortcode extends WP_Ajax_UnitTestCase {
|
||||
const SHORTCODE_RETURN_VALUE = 'TEST';
|
||||
private static $media_id;
|
||||
public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
|
||||
self::$media_id = self::factory()->attachment->create_object(
|
||||
get_temp_dir() . 'canola.jpg',
|
||||
0,
|
||||
array(
|
||||
'post_mime_type' => 'image/jpeg',
|
||||
'post_excerpt' => 'A sample caption',
|
||||
'post_name' => 'restapi-client-fixture-attachment',
|
||||
'post_title' => 'REST API Client Fixture: Attachment',
|
||||
'post_date' => '2017-02-14 00:00:00',
|
||||
'post_date_gmt' => '2017-02-14 00:00:00',
|
||||
'post_author' => 0,
|
||||
)
|
||||
);
|
||||
}
|
||||
/**
|
||||
* @dataProvider shortcode_provider
|
||||
*/
|
||||
public function test_parse_shortcode( array $payload, $expected ) {
|
||||
add_shortcode( 'test', array( $this, 'shortcode_test' ) );
|
||||
|
||||
$_POST = array_merge(
|
||||
array(
|
||||
'action' => 'paser-media-shortcode',
|
||||
'type' => '',
|
||||
),
|
||||
$payload
|
||||
);
|
||||
// Make the request.
|
||||
try {
|
||||
$this->_handleAjax( 'parse-media-shortcode' );
|
||||
} catch ( WPAjaxDieContinueException $e ) {
|
||||
unset( $e );
|
||||
}
|
||||
// Get the response, it is in heartbeat's response.
|
||||
$response = json_decode( $this->_last_response, true );
|
||||
$body = $response['data']['body'] ?? '';
|
||||
if ( $body ) {
|
||||
$this->assertStringNotContainsString( self::SHORTCODE_RETURN_VALUE, $body );
|
||||
}
|
||||
$this->assertSame( $expected['success'], $response['success'] );
|
||||
}
|
||||
|
||||
public function shortcode_test() {
|
||||
return self::SHORTCODE_RETURN_VALUE;
|
||||
}
|
||||
|
||||
public function shortcode_provider() {
|
||||
return array(
|
||||
'gallery_shortcode_is_allowed' => array(
|
||||
'payload' => array( 'shortcode' => '[gallery ids=" ' . self::$media_id . '"]' ),
|
||||
'expected' => array( 'success' => true ),
|
||||
),
|
||||
'gallery_and_custom_test_shortcode_is_not_allowed' => array(
|
||||
'payload' => array( 'shortcode' => '[gallery ids=" ' . self::$media_id . '"] [test]' ),
|
||||
'expected' => array( 'success' => false ),
|
||||
),
|
||||
'custom_test_shortcode_is_not_allowed' => array(
|
||||
'payload' => array( 'shortcode' => '[test]' ),
|
||||
'expected' => array( 'success' => false ),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user