diff --git a/wordpress.org/public_html/wp-content/plugins/photo-directory/inc/posts.php b/wordpress.org/public_html/wp-content/plugins/photo-directory/inc/posts.php index 8e2e5b326f..088e310903 100644 --- a/wordpress.org/public_html/wp-content/plugins/photo-directory/inc/posts.php +++ b/wordpress.org/public_html/wp-content/plugins/photo-directory/inc/posts.php @@ -35,6 +35,9 @@ public static function init() { // Sync photo post content to photo media on update. add_action( 'post_updated', [ __CLASS__, 'sync_photo_post_to_photo_media_on_update' ], 5, 3 ); + // Photo content is plain text (the alternative text), never post markup. + add_filter( 'the_content', [ __CLASS__, 'render_content_as_plain_text' ], PHP_INT_MIN ); + // Offset subsequent paginations of front page by number of posts on front page. add_action( 'pre_get_posts', [ __CLASS__, 'offset_front_page_paginations' ], 11 ); // Fix pages count for front page paginations. @@ -256,6 +259,35 @@ public static function use_photo_url_instead_of_media_permalink_url( $url, $post return wp_get_attachment_url( $post_id ); } + /** + * Renders a photo's content as the plain text it is. + * + * A photo's content is the alternative text submitted with it. The submit + * form and its sanitization treat that as plain text, so the content must + * not be interpreted as post markup on output either. It is escaped here, + * ahead of every other 'the_content' callback, so that they only ever see + * text. + * + * Keys on the global post, like core's own content callbacks, so it applies + * to whatever 'the_content' is run for while a photo is the current post. + * The reverse also holds: a photo's content filtered while another post is + * global, such as an excerpt built outside the loop, is not escaped here. + * Nothing on the site does that. + * + * @param string $content Post content. + * @return string + */ + public static function render_content_as_plain_text( $content ) { + if ( Registrations::get_post_type() !== get_post_type() ) { + return $content; + } + + $content = esc_html( $content ); + + // Shortcode and URL syntax stay visible text: hide the characters shortcodes and embeds key on. + return str_replace( [ '[', '://' ], [ '[', '://' ], $content ); + } + /** * Syncs the photo post content to the caption for the associated photo media. *