Index: /branches/4.9/src/wp-admin/includes/ajax-actions.php
===================================================================
--- /branches/4.9/src/wp-admin/includes/ajax-actions.php	(revision 54568)
+++ /branches/4.9/src/wp-admin/includes/ajax-actions.php	(revision 54569)
@@ -2472,5 +2472,5 @@
 	// Filter query clauses to include filenames.
 	if ( isset( $query['s'] ) ) {
-		add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
+		add_filter( 'wp_allow_query_attachment_by_filename', '__return_true' );
 	}
 
Index: /branches/4.9/src/wp-admin/includes/post.php
===================================================================
--- /branches/4.9/src/wp-admin/includes/post.php	(revision 54568)
+++ /branches/4.9/src/wp-admin/includes/post.php	(revision 54569)
@@ -1175,5 +1175,5 @@
 	// Filter query clauses to include filenames.
 	if ( isset( $q['s'] ) ) {
-		add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
+		add_filter( 'wp_allow_query_attachment_by_filename', '__return_true' );
 	}
 
Index: /branches/4.9/src/wp-includes/class-wp-query.php
===================================================================
--- /branches/4.9/src/wp-includes/class-wp-query.php	(revision 54568)
+++ /branches/4.9/src/wp-includes/class-wp-query.php	(revision 54569)
@@ -438,4 +438,11 @@
 	private $compat_methods = array( 'init_query_flags', 'parse_tax_query' );
 
+	/**
+	 * Controls whether an attachment query should include filenames or not.
+	 *
+	 * @since 6.0.3
+	 * @var bool
+	 */
+	protected $allow_query_attachment_by_filename = false;
 	/**
 	 * Resets query flags to false.
@@ -1299,5 +1306,10 @@
 
 			$like = $n . $wpdb->esc_like( $term ) . $n;
-			$search .= $wpdb->prepare( "{$searchand}(({$wpdb->posts}.post_title $like_op %s) $andor_op ({$wpdb->posts}.post_excerpt $like_op %s) $andor_op ({$wpdb->posts}.post_content $like_op %s))", $like, $like, $like );
+
+			if ( ! empty( $this->allow_query_attachment_by_filename ) ) {
+				$search .= $wpdb->prepare( "{$searchand}(({$wpdb->posts}.post_title $like_op %s) $andor_op ({$wpdb->posts}.post_excerpt $like_op %s) $andor_op ({$wpdb->posts}.post_content $like_op %s) $andor_op (sq1.meta_value $like_op %s))", $like, $like, $like, $like );
+			} else {
+				$search .= $wpdb->prepare( "{$searchand}(({$wpdb->posts}.post_title $like_op %s) $andor_op ({$wpdb->posts}.post_excerpt $like_op %s) $andor_op ({$wpdb->posts}.post_content $like_op %s))", $like, $like, $like );
+			}
 			$searchand = ' AND ';
 		}
@@ -1635,4 +1647,14 @@
 		$q = $this->fill_query_vars($q);
 
+		/**
+		 * Filters whether an attachment query should include filenames or not.
+		 *
+		 * @since 6.0.3
+		 *
+		 * @param bool $allow_query_attachment_by_filename Whether or not to include filenames.
+		 */
+		$this->allow_query_attachment_by_filename = apply_filters( 'wp_allow_query_attachment_by_filename', false );
+		remove_all_filters( 'wp_allow_query_attachment_by_filename' );
+
 		// Parse meta query
 		$this->meta_query = new WP_Meta_Query();
@@ -2039,5 +2061,5 @@
 		}
 
-		if ( !empty( $this->tax_query->queries ) || !empty( $this->meta_query->queries ) ) {
+		if ( ! empty( $this->tax_query->queries ) || ! empty( $this->meta_query->queries ) || ! empty( $this->allow_query_attachment_by_filename ) ) {
 			$groupby = "{$wpdb->posts}.ID";
 		}
@@ -2111,4 +2133,8 @@
 		}
 		$where .= $search . $whichauthor . $whichmimetype;
+
+		if ( ! empty( $this->allow_query_attachment_by_filename ) ) {
+			$join .= " LEFT JOIN {$wpdb->postmeta} AS sq1 ON ( {$wpdb->posts}.ID = sq1.post_id AND sq1.meta_key = '_wp_attached_file' )";
+		}
 
 		if ( ! empty( $this->meta_query->queries ) ) {
Index: /branches/4.9/src/wp-includes/comment.php
===================================================================
--- /branches/4.9/src/wp-includes/comment.php	(revision 54568)
+++ /branches/4.9/src/wp-includes/comment.php	(revision 54569)
@@ -2196,4 +2196,13 @@
 	}
 
+	$filter_comment = false;
+	if ( ! has_filter( 'pre_comment_content', 'wp_filter_kses' ) ) {
+		$filter_comment = ! user_can( isset( $comment['user_id'] ) ? $comment['user_id'] : 0, 'unfiltered_html' );
+	}
+
+	if ( $filter_comment ) {
+		add_filter( 'pre_comment_content', 'wp_filter_kses' );
+	}
+
 	// Escape data pulled from DB.
 	$comment = wp_slash($comment);
@@ -2205,4 +2214,8 @@
 
 	$commentarr = wp_filter_comment( $commentarr );
+
+	if ( $filter_comment ) {
+		remove_filter( 'pre_comment_content', 'wp_filter_kses' );
+	}
 
 	// Now extract the merged array.
Index: /branches/4.9/src/wp-includes/customize/class-wp-customize-header-image-control.php
===================================================================
--- /branches/4.9/src/wp-includes/customize/class-wp-customize-header-image-control.php	(revision 54568)
+++ /branches/4.9/src/wp-includes/customize/class-wp-customize-header-image-control.php	(revision 54569)
@@ -104,8 +104,8 @@
 
 			<button type="button" class="choice thumbnail"
-				data-customize-image-value="{{{data.header.url}}}"
+				data-customize-image-value="{{data.header.url}}"
 				data-customize-header-image-data="{{JSON.stringify(data.header)}}">
 				<span class="screen-reader-text"><?php _e( 'Set image' ); ?></span>
-				<img src="{{{data.header.thumbnail_url}}}" alt="{{{data.header.alt_text || data.header.description}}}">
+				<img src="{{data.header.thumbnail_url}}" alt="{{data.header.alt_text || data.header.description}}" />
 			</button>
 
Index: /branches/4.9/src/wp-includes/customize/class-wp-customize-site-icon-control.php
===================================================================
--- /branches/4.9/src/wp-includes/customize/class-wp-customize-site-icon-control.php	(revision 54568)
+++ /branches/4.9/src/wp-includes/customize/class-wp-customize-site-icon-control.php	(revision 54569)
@@ -67,5 +67,5 @@
 								<img src="{{ data.attachment.sizes.full ? data.attachment.sizes.full.url : data.attachment.url }}" alt="<?php esc_attr_e( 'Preview as a browser icon' ); ?>"/>
 							</div>
-							<span class="browser-title" aria-hidden="true"><?php bloginfo( 'name' ); ?></span>
+							<span class="browser-title" aria-hidden="true"><?php echo esc_js( get_bloginfo( 'name' ) ); ?></span>
 						</div>
 						<img class="app-icon-preview" src="{{ data.attachment.sizes.full ? data.attachment.sizes.full.url : data.attachment.url }}" alt="<?php esc_attr_e( 'Preview as an app icon' ); ?>"/>
Index: /branches/4.9/src/wp-includes/date.php
===================================================================
--- /branches/4.9/src/wp-includes/date.php	(revision 54568)
+++ /branches/4.9/src/wp-includes/date.php	(revision 54569)
@@ -146,6 +146,6 @@
 	 */
 	public function __construct( $date_query, $default_column = 'post_date' ) {
-		if ( isset( $date_query['relation'] ) && 'OR' === strtoupper( $date_query['relation'] ) ) {
-			$this->relation = 'OR';
+		if ( isset( $date_query['relation'] ) ) {
+			$this->relation = $this->sanitize_relation( $date_query['relation'] );
 		} else {
 			$this->relation = 'AND';
@@ -225,4 +225,7 @@
 			$this->validate_date_values( $queries );
 		}
+
+		// Sanitize the relation parameter.
+		$queries['relation'] = $this->sanitize_relation( $queries['relation'] );
 
 		foreach ( $queries as $key => $q ) {
@@ -999,3 +1002,19 @@
 		return $wpdb->prepare( "DATE_FORMAT( $column, %s ) $compare %f", $format, $time );
 	}
+
+	/**
+	 * Sanitizes a 'relation' operator.
+	 *
+	 * @since 6.0.3
+	 *
+	 * @param string $relation Raw relation key from the query argument.
+	 * @return string Sanitized relation ('AND' or 'OR').
+	 */
+	public function sanitize_relation( $relation ) {
+		if ( 'OR' === strtoupper( $relation ) ) {
+			return 'OR';
+		} else {
+			return 'AND';
+		}
+	}
 }
Index: /branches/4.9/src/wp-includes/deprecated.php
===================================================================
--- /branches/4.9/src/wp-includes/deprecated.php	(revision 54568)
+++ /branches/4.9/src/wp-includes/deprecated.php	(revision 54569)
@@ -3945,2 +3945,20 @@
 	}
 }
+
+/**
+ * Filter the SQL clauses of an attachment query to include filenames.
+ *
+ * @since 4.7.0
+ * @deprecated 6.0.3
+ * @access private
+ *
+ * @param array $clauses An array including WHERE, GROUP BY, JOIN, ORDER BY,
+ *                       DISTINCT, fields (SELECT), and LIMITS clauses.
+ * @return array The unmodified clauses.
+ */
+function _filter_query_attachment_filenames( $clauses ) {
+	_deprecated_function( __FUNCTION__, '6.0.3', 'add_filter( "wp_allow_query_attachment_by_filename", "__return_true" )');
+	remove_filter( 'posts_clauses', __FUNCTION__ );
+	return $clauses;
+}
+
Index: /branches/4.9/src/wp-includes/functions.php
===================================================================
--- /branches/4.9/src/wp-includes/functions.php	(revision 54568)
+++ /branches/4.9/src/wp-includes/functions.php	(revision 54569)
@@ -2378,5 +2378,5 @@
 			if ( $type !== $real_mime ) {
 				/*
-				 * Everything else including image/* and application/*: 
+				 * Everything else including image/* and application/*:
 				 * If the real content type doesn't match the file extension, assume it's dangerous.
 				 */
@@ -2387,5 +2387,5 @@
 	}
 
-	// The mime type must be allowed 
+	// The mime type must be allowed
 	if ( $type ) {
 		$allowed = get_allowed_mime_types();
@@ -2661,7 +2661,10 @@
 		$html = __( 'The link you followed has expired.' );
 		if ( wp_get_referer() ) {
-			$html .= '</p><p>';
-			$html .= sprintf( '<a href="%s">%s</a>',
-				esc_url( remove_query_arg( 'updated', wp_get_referer() ) ),
+			$wp_http_referer = remove_query_arg( 'updated', wp_get_referer() );
+			$wp_http_referer = wp_validate_redirect( esc_url_raw( $wp_http_referer ) );
+			$html           .= '</p><p>';
+			$html           .= sprintf(
+				'<a href="%s">%s</a>',
+				esc_url( $wp_http_referer ),
 				__( 'Please try again.' )
 			);
Index: /branches/4.9/src/wp-includes/media-template.php
===================================================================
--- /branches/4.9/src/wp-includes/media-template.php	(revision 54568)
+++ /branches/4.9/src/wp-includes/media-template.php	(revision 54569)
@@ -1253,5 +1253,5 @@
 				<img id="preview-favicon" src="{{ data.url }}" alt="<?php esc_attr_e( 'Preview as a browser icon' ); ?>"/>
 			</div>
-			<span class="browser-title" aria-hidden="true"><?php bloginfo( 'name' ); ?></span>
+			<span class="browser-title" aria-hidden="true"><?php echo esc_js( get_bloginfo( 'name' ) ); ?></span>
 		</div>
 
Index: /branches/4.9/src/wp-includes/pluggable.php
===================================================================
--- /branches/4.9/src/wp-includes/pluggable.php	(revision 54568)
+++ /branches/4.9/src/wp-includes/pluggable.php	(revision 54569)
@@ -313,4 +313,6 @@
 	$phpmailer->clearCustomHeaders();
 	$phpmailer->clearReplyTos();
+	$phpmailer->Body    = '';
+	$phpmailer->AltBody = '';
 
 	// From email and name
Index: /branches/4.9/src/wp-includes/post.php
===================================================================
--- /branches/4.9/src/wp-includes/post.php	(revision 54568)
+++ /branches/4.9/src/wp-includes/post.php	(revision 54569)
@@ -1706,5 +1706,97 @@
 	}
 
-	return $post_type->publicly_queryable || ( $post_type->_builtin && $post_type->public );
+	if ( ! is_object( $post_type ) ) {
+		return false;
+	}
+
+	$is_viewable = $post_type->publicly_queryable || ( $post_type->_builtin && $post_type->public );
+
+	/**
+	 * Filters whether a post type is considered "viewable".
+	 *
+	 * The returned filtered value must be a boolean type to ensure
+	 * `is_post_type_viewable()` only returns a boolean. This strictness
+	 * is by design to maintain backwards-compatibility and guard against
+	 * potential type errors in PHP 8.1+. Non-boolean values (even falsey
+	 * and truthy values) will result in the function returning false.
+	 *
+	 * @since 5.9.0
+	 *
+	 * @param bool         $is_viewable Whether the post type is "viewable" (strict type).
+	 * @param WP_Post_Type $post_type   Post type object.
+	 */
+	return true === apply_filters( 'is_post_type_viewable', $is_viewable, $post_type );
+}
+
+/**
+ * Determines whether a post status is considered "viewable".
+ *
+ * For built-in post statuses such as publish and private, the 'public' value will be evaluated.
+ * For all others, the 'publicly_queryable' value will be used.
+ *
+ * @since 5.7.0
+ * @since 5.9.0 Added `is_post_status_viewable` hook to filter the result.
+ *
+ * @param string|stdClass $post_status Post status name or object.
+ * @return bool Whether the post status should be considered viewable.
+ */
+function is_post_status_viewable( $post_status ) {
+	if ( is_scalar( $post_status ) ) {
+		$post_status = get_post_status_object( $post_status );
+
+		if ( ! $post_status ) {
+			return false;
+		}
+	}
+
+	if (
+		! is_object( $post_status ) ||
+		$post_status->internal ||
+		$post_status->protected
+	) {
+		return false;
+	}
+
+	$is_viewable = $post_status->publicly_queryable || ( $post_status->_builtin && $post_status->public );
+
+	/**
+	 * Filters whether a post status is considered "viewable".
+	 *
+	 * The returned filtered value must be a boolean type to ensure
+	 * `is_post_status_viewable()` only returns a boolean. This strictness
+	 * is by design to maintain backwards-compatibility and guard against
+	 * potential type errors in PHP 8.1+. Non-boolean values (even falsey
+	 * and truthy values) will result in the function returning false.
+	 *
+	 * @since 5.9.0
+	 *
+	 * @param bool     $is_viewable Whether the post status is "viewable" (strict type).
+	 * @param stdClass $post_status Post status object.
+	 */
+	return true === apply_filters( 'is_post_status_viewable', $is_viewable, $post_status );
+}
+
+/**
+ * Determines whether a post is publicly viewable.
+ *
+ * Posts are considered publicly viewable if both the post status and post type
+ * are viewable.
+ *
+ * @since 5.7.0
+ *
+ * @param int|WP_Post|null $post Optional. Post ID or post object. Defaults to global $post.
+ * @return bool Whether the post is publicly viewable.
+ */
+function is_post_publicly_viewable( $post = null ) {
+	$post = get_post( $post );
+
+	if ( ! $post ) {
+		return false;
+	}
+
+	$post_type   = get_post_type( $post );
+	$post_status = get_post_status( $post );
+
+	return is_post_type_viewable( $post_type ) && is_post_status_viewable( $post_status );
 }
 
@@ -6456,31 +6548,2 @@
 	return $post_name;
 }
-
-/**
- * Filter the SQL clauses of an attachment query to include filenames.
- *
- * @since 4.7.0
- * @access private
- *
- * @global wpdb $wpdb WordPress database abstraction object.
- *
- * @param array $clauses An array including WHERE, GROUP BY, JOIN, ORDER BY,
- *                       DISTINCT, fields (SELECT), and LIMITS clauses.
- * @return array The modified clauses.
- */
-function _filter_query_attachment_filenames( $clauses ) {
-	global $wpdb;
-	remove_filter( 'posts_clauses', __FUNCTION__ );
-
-	// Add a LEFT JOIN of the postmeta table so we don't trample existing JOINs.
-	$clauses['join'] .= " LEFT JOIN {$wpdb->postmeta} AS sq1 ON ( {$wpdb->posts}.ID = sq1.post_id AND sq1.meta_key = '_wp_attached_file' )";
-
-	$clauses['groupby'] = "{$wpdb->posts}.ID";
-
-	$clauses['where'] = preg_replace(
-		"/\({$wpdb->posts}.post_content (NOT LIKE|LIKE) (\'[^']+\')\)/",
-		"$0 OR ( sq1.meta_value $1 $2 )",
-		$clauses['where'] );
-
-	return $clauses;
-}
Index: /branches/4.9/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php
===================================================================
--- /branches/4.9/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php	(revision 54568)
+++ /branches/4.9/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php	(revision 54569)
@@ -49,5 +49,5 @@
 		// Filter query clauses to include filenames.
 		if ( isset( $query_args['s'] ) ) {
-			add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
+			add_filter( 'wp_allow_query_attachment_by_filename', '__return_true' );
 		}
 
Index: /branches/4.9/src/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php
===================================================================
--- /branches/4.9/src/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php	(revision 54568)
+++ /branches/4.9/src/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php	(revision 54569)
@@ -128,4 +128,33 @@
 
 	/**
+	 * Checks if the terms for a post can be read.
+	 *
+	 * @since 6.0.3
+	 *
+	 * @param WP_Post         $post    Post object.
+	 * @param WP_REST_Request $request Full details about the request.
+	 * @return bool Whether the terms for the post can be read.
+	 */
+	public function check_read_terms_permission_for_post( $post, $request ) {
+		// If the requested post isn't associated with this taxonomy, deny access.
+		if ( ! is_object_in_taxonomy( $post->post_type, $this->taxonomy ) ) {
+			return false;
+		}
+
+		// Grant access if the post is publicly viewable.
+		if ( is_post_publicly_viewable( $post ) ) {
+			return true;
+		}
+
+		// Otherwise grant access if the post is readable by the logged in user.
+		if ( current_user_can( 'read_post', $post->ID ) ) {
+			return true;
+		}
+
+		// Otherwise, deny access.
+		return false;
+	}
+
+	/**
 	 * Checks if a request has access to read terms in the specified taxonomy.
 	 *
@@ -137,10 +166,41 @@
 	public function get_items_permissions_check( $request ) {
 		$tax_obj = get_taxonomy( $this->taxonomy );
+
 		if ( ! $tax_obj || ! $this->check_is_taxonomy_allowed( $this->taxonomy ) ) {
 			return false;
 		}
+
 		if ( 'edit' === $request['context'] && ! current_user_can( $tax_obj->cap->edit_terms ) ) {
-			return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit terms in this taxonomy.' ), array( 'status' => rest_authorization_required_code() ) );
-		}
+			return new WP_Error(
+				'rest_forbidden_context',
+				__( 'Sorry, you are not allowed to edit terms in this taxonomy.' ),
+				array( 'status' => rest_authorization_required_code() )
+			);
+		}
+
+		if ( ! empty( $request['post'] ) ) {
+			$post = get_post( $request['post'] );
+
+			if ( ! $post ) {
+				return new WP_Error(
+					'rest_post_invalid_id',
+					__( 'Invalid post ID.' ),
+					array(
+						'status' => 400,
+					)
+				);
+			}
+
+			if ( ! $this->check_read_terms_permission_for_post( $post, $request ) ) {
+				return new WP_Error(
+					'rest_forbidden_context',
+					__( 'Sorry, you are not allowed to view terms for this post.' ),
+					array(
+						'status' => rest_authorization_required_code(),
+					)
+				);
+			}
+		}
+
 		return true;
 	}
Index: /branches/4.9/src/wp-includes/widgets.php
===================================================================
--- /branches/4.9/src/wp-includes/widgets.php	(revision 54568)
+++ /branches/4.9/src/wp-includes/widgets.php	(revision 54569)
@@ -1397,5 +1397,5 @@
 	if ( is_wp_error($rss) ) {
 		if ( is_admin() || current_user_can('manage_options') )
-			echo '<p><strong>' . __( 'RSS Error:' ) . '</strong> ' . $rss->get_error_message() . '</p>';
+			echo '<p><strong>' . __( 'RSS Error:' ) . '</strong> ' . esc_html( $rss->get_error_message() ) . '</p>';
 		return;
 	}
@@ -1506,5 +1506,5 @@
 
 	if ( ! empty( $args['error'] ) ) {
-		echo '<p class="widget-error"><strong>' . __( 'RSS Error:' ) . '</strong> ' . $args['error'] . '</p>';
+		echo '<p class="widget-error"><strong>' . __( 'RSS Error:' ) . '</strong> ' . esc_html( $args['error'] ) . '</p>';
 	}
 
Index: /branches/4.9/src/wp-mail.php
===================================================================
--- /branches/4.9/src/wp-mail.php	(revision 54568)
+++ /branches/4.9/src/wp-mail.php	(revision 54569)
@@ -60,4 +60,7 @@
 	wp_die( __('There doesn&#8217;t seem to be any new mail.') );
 }
+
+// Always run as an unauthenticated user.
+wp_set_current_user( 0 );
 
 for ( $i = 1; $i <= $count; $i++ ) {
@@ -125,9 +128,7 @@
 				$author = sanitize_email($author);
 				if ( is_email($author) ) {
-					/* translators: Post author email address */
-					echo '<p>' . sprintf(__('Author is %s'), $author) . '</p>';
 					$userdata = get_user_by('email', $author);
 					if ( ! empty( $userdata ) ) {
-						$post_author = $userdata->ID;
+						$post_author  = $userdata->ID;
 						$author_found = true;
 					}
Index: /branches/4.9/src/wp-trackback.php
===================================================================
--- /branches/4.9/src/wp-trackback.php	(revision 54568)
+++ /branches/4.9/src/wp-trackback.php	(revision 54569)
@@ -13,4 +13,7 @@
 	wp( array( 'tb' => '1' ) );
 }
+
+// Always run as an unauthenticated user.
+wp_set_current_user( 0 );
 
 /**
Index: /branches/4.9/tests/phpunit/tests/query/search.php
===================================================================
--- /branches/4.9/tests/phpunit/tests/query/search.php	(revision 54568)
+++ /branches/4.9/tests/phpunit/tests/query/search.php	(revision 54569)
@@ -371,5 +371,5 @@
 
 		add_post_meta( $attachment, '_wp_attached_file', 'some-image1.png', true );
-		add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
+		add_filter( 'wp_allow_query_attachment_by_filename', '__return_true' );
 
 		// Pass post_type a string value.
@@ -397,5 +397,5 @@
 
 		add_post_meta( $attachment, '_wp_attached_file', 'some-image2.png', true );
-		add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
+		add_filter( 'wp_allow_query_attachment_by_filename', '__return_true' );
 
 		// Pass post_type an array value.
@@ -448,5 +448,5 @@
 		add_post_meta( $attachment, '_wp_attached_file', 'some-image4.png', true );
 		add_post_meta( $attachment, '_test_meta_key', 'value', true );
-		add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
+		add_filter( 'wp_allow_query_attachment_by_filename', '__return_true' );
 
 		// Pass post_type a string value.
@@ -484,5 +484,5 @@
 
 		add_post_meta( $attachment, '_wp_attached_file', 'some-image5.png', true );
-		add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
+		add_filter( 'wp_allow_query_attachment_by_filename', '__return_true' );
 
 		// Pass post_type a string value.
@@ -507,20 +507,35 @@
 	 * @ticket 22744
 	 */
-	public function test_filter_query_attachment_filenames_unhooks_itself() {
-		add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
-
-		apply_filters( 'posts_clauses', array(
-			'where'    => '',
-			'groupby'  => '',
-			'join'     => '',
-			'orderby'  => '',
-			'distinct' => '',
-			'fields'   => '',
-			'limit'    => '',
-		) );
-
-		$result = has_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
-
-		$this->assertFalse( $result );
+	public function test_wp_query_removes_filter_wp_allow_query_attachment_by_filename() {
+		$attachment = self::factory()->post->create(
+			array(
+				'post_type'    => 'attachment',
+				'post_status'  => 'publish',
+				'post_title'   => 'bar foo',
+				'post_content' => 'foo bar',
+				'post_excerpt' => 'This post has foo',
+			)
+		);
+
+		add_post_meta( $attachment, '_wp_attached_file', 'some-image1.png', true );
+		add_filter( 'wp_allow_query_attachment_by_filename', '__return_true' );
+
+		$q = new WP_Query(
+			array(
+				's'           => 'image1',
+				'fields'      => 'ids',
+				'post_type'   => 'attachment',
+				'post_status' => 'inherit',
+			)
+		);
+
+		$this->assertSame( array( $attachment ), $q->posts );
+
+		/*
+		 * WP_Query should have removed the wp_allow_query_attachment_by_filename filter
+		 * and thus not match the attachment created above
+		 */
+		$q->get_posts();
+		$this->assertEmpty( $q->posts );
 	}
 
Index: /branches/4.9/tests/phpunit/tests/rest-api/rest-comments-controller.php
===================================================================
--- /branches/4.9/tests/phpunit/tests/rest-api/rest-comments-controller.php	(revision 54568)
+++ /branches/4.9/tests/phpunit/tests/rest-api/rest-comments-controller.php	(revision 54569)
@@ -2605,4 +2605,5 @@
 				'author_name'       => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
 				'author_user_agent' => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
+				'author'            => self::$editor_id,
 			), array(
 				'content' => array(
@@ -2612,4 +2613,5 @@
 				'author_name'       => 'div strong',
 				'author_user_agent' => 'div strong',
+				'author'            => self::$editor_id,
 			) );
 		} else {
@@ -2619,4 +2621,5 @@
 				'author_name'       => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
 				'author_user_agent' => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
+				'author'            => self::$editor_id,
 			), array(
 				'content' => array(
@@ -2626,4 +2629,5 @@
 				'author_name'       => 'div strong',
 				'author_user_agent' => 'div strong',
+				'author'            => self::$editor_id,
 			) );
 		}
@@ -2637,4 +2641,5 @@
 			'author_name'       => '\\\&\\\ &amp; &invalid; < &lt; &amp;lt;',
 			'author_user_agent' => '\\\&\\\ &amp; &invalid; < &lt; &amp;lt;',
+			'author'            => self::$superadmin_id,
 		), array(
 			'content' => array(
@@ -2644,4 +2649,5 @@
 			'author_name'       => '\\\&amp;\\\ &amp; &amp;invalid; &lt; &lt; &amp;lt;',
 			'author_user_agent' => '\\\&\\\ &amp; &invalid; &lt; &lt; &amp;lt;',
+			'author'            => self::$superadmin_id,
 		) );
 	}
@@ -2654,4 +2660,5 @@
 			'author_name'       => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
 			'author_user_agent' => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
+			'author'            => self::$superadmin_id,
 		), array(
 			'content' => array(
@@ -2661,4 +2668,5 @@
 			'author_name'       => 'div strong',
 			'author_user_agent' => 'div strong',
+			'author'            => self::$superadmin_id,
 		) );
 	}
