// phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
$utf8_pcre = @preg_match( '/^./u', 'a' );
if ( ! seems_utf8( $filename ) ) {
$_ext = pathinfo( $filename, PATHINFO_EXTENSION );
$_name = pathinfo( $filename, PATHINFO_FILENAME );
$filename = sanitize_title_with_dashes( $_name ) . '.' . $_ext;
$filename = preg_replace( "#\x{00a0}#siu", ' ', $filename );
* Filters the list of characters to remove from a filename.
* @param string[] $special_chars Array of characters to remove.
* @param string $filename_raw The original filename to be sanitized.
$special_chars = apply_filters( 'sanitize_file_name_chars', $special_chars, $filename_raw );
$filename = str_replace( $special_chars, '', $filename );
$filename = str_replace( array( '%20', '+' ), '-', $filename );
$filename = preg_replace( '/[\r\n\t -]+/', '-', $filename );
$filename = trim( $filename, '.-_' );
if ( false === strpos( $filename, '.' ) ) {
$mime_types = wp_get_mime_types();
$filetype = wp_check_filetype( 'test.' . $filename, $mime_types );
if ( $filetype['ext'] === $filename ) {
$filename = 'unnamed-file.' . $filetype['ext'];
// Split the filename into a base and extension[s].
$parts = explode( '.', $filename );
// Return if only one extension.
if ( count( $parts ) <= 2 ) {
/** This filter is documented in wp-includes/formatting.php */
return apply_filters( 'sanitize_file_name', $filename, $filename_raw );
// Process multiple extensions.
$filename = array_shift( $parts );
$extension = array_pop( $parts );
$mimes = get_allowed_mime_types();
* Loop over any intermediate extensions. Postfix them with a trailing underscore
* if they are a 2 - 5 character long alpha string not in the allowed extension list.
foreach ( (array) $parts as $part ) {
$filename .= '.' . $part;
if ( preg_match( '/^[a-zA-Z]{2,5}\d?$/', $part ) ) {
foreach ( $mimes as $ext_preg => $mime_match ) {
$ext_preg = '!^(' . $ext_preg . ')$!i';
if ( preg_match( $ext_preg, $part ) ) {
$filename .= '.' . $extension;
* Filters a sanitized filename string.
* @param string $filename Sanitized filename.
* @param string $filename_raw The filename prior to sanitization.
return apply_filters( 'sanitize_file_name', $filename, $filename_raw );
* Sanitizes a username, stripping out unsafe characters.
* Removes tags, octets, entities, and if strict is enabled, will only keep
* alphanumeric, _, space, ., -, @. After sanitizing, it passes the username,
* raw username (the username in the parameter), and the value of $strict as
* parameters for the {@see 'sanitize_user'} filter.
* @param string $username The username to be sanitized.
* @param bool $strict Optional. If set limits $username to specific characters.
* @return string The sanitized username, after passing through filters.
function sanitize_user( $username, $strict = false ) {
$raw_username = $username;
$username = wp_strip_all_tags( $username );
$username = remove_accents( $username );
$username = preg_replace( '|%([a-fA-F0-9][a-fA-F0-9])|', '', $username );
$username = preg_replace( '/&.+?;/', '', $username );
// If strict, reduce to ASCII for max portability.
$username = preg_replace( '|[^a-z0-9 _.\-@]|i', '', $username );
$username = trim( $username );
// Consolidate contiguous whitespace.
$username = preg_replace( '|\s+|', ' ', $username );
* Filters a sanitized username string.
* @param string $username Sanitized username.
* @param string $raw_username The username prior to sanitization.
* @param bool $strict Whether to limit the sanitization to specific characters.
return apply_filters( 'sanitize_user', $username, $raw_username, $strict );
* Sanitizes a string key.
* Keys are used as internal identifiers. Lowercase alphanumeric characters,
* dashes, and underscores are allowed.
* @param string $key String key
* @return string Sanitized key
function sanitize_key( $key ) {
$key = strtolower( $key );
$key = preg_replace( '/[^a-z0-9_\-]/', '', $key );
* Filters a sanitized key string.
* @param string $key Sanitized key.
* @param string $raw_key The key prior to sanitization.
return apply_filters( 'sanitize_key', $key, $raw_key );
* Sanitizes a string into a slug, which can be used in URLs or HTML attributes.
* By default, converts accent characters to ASCII characters and further
* limits the output to alphanumeric characters, underscore (_) and dash (-)
* through the {@see 'sanitize_title'} filter.
* If `$title` is empty and `$fallback_title` is set, the latter will be used.
* @param string $title The string to be sanitized.
* @param string $fallback_title Optional. A title to use if $title is empty. Default empty.
* @param string $context Optional. The operation for which the string is sanitized.
* When set to 'save', the string runs through remove_accents().
* @return string The sanitized string.
function sanitize_title( $title, $fallback_title = '', $context = 'save' ) {
if ( 'save' === $context ) {
$title = remove_accents( $title );
* Filters a sanitized title string.
* @param string $title Sanitized title.
* @param string $raw_title The title prior to sanitization.
* @param string $context The context for which the title is being sanitized.
$title = apply_filters( 'sanitize_title', $title, $raw_title, $context );
if ( '' === $title || false === $title ) {
$title = $fallback_title;
* Sanitizes a title with the 'query' context.
* Used for querying the database for a value from URL.
* @param string $title The string to be sanitized.
* @return string The sanitized string.
function sanitize_title_for_query( $title ) {
return sanitize_title( $title, '', 'query' );
* Sanitizes a title, replacing whitespace and a few other characters with dashes.
* Limits the output to alphanumeric characters, underscore (_) and dash (-).
* Whitespace becomes a dash.
* @param string $title The title to be sanitized.
* @param string $raw_title Optional. Not used. Default empty.
* @param string $context Optional. The operation for which the string is sanitized.
* When set to 'save', additional entities are converted to hyphens
* or stripped entirely. Default 'display'.
* @return string The sanitized title.
function sanitize_title_with_dashes( $title, $raw_title = '', $context = 'display' ) {
$title = strip_tags( $title );
// Preserve escaped octets.
$title = preg_replace( '|%([a-fA-F0-9][a-fA-F0-9])|', '---$1---', $title );
// Remove percent signs that are not part of an octet.
$title = str_replace( '%', '', $title );
$title = preg_replace( '|---([a-fA-F0-9][a-fA-F0-9])---|', '%$1', $title );
if ( seems_utf8( $title ) ) {
if ( function_exists( 'mb_strtolower' ) ) {
$title = mb_strtolower( $title, 'UTF-8' );
$title = utf8_uri_encode( $title, 200 );
$title = strtolower( $title );
if ( 'save' === $context ) {
// Convert  , &ndash, and &mdash to hyphens.
$title = str_replace( array( '%c2%a0', '%e2%80%93', '%e2%80%94' ), '-', $title );
// Convert  , &ndash, and &mdash HTML entities to hyphens.
$title = str_replace( array( ' ', ' ', '–', '–', '—', '—' ), '-', $title );
// Convert forward slash to hyphen.
$title = str_replace( '/', '-', $title );
// Strip these characters entirely.
// ©, ®, °, &hellip, and &trade.
// Grave accent, macron, caron.
// Convert × to 'x'.
$title = str_replace( '%c3%97', 'x', $title );
$title = preg_replace( '/&.+?;/', '', $title );
$title = str_replace( '.', '-', $title );
$title = preg_replace( '/[^%a-z0-9 _-]/', '', $title );
$title = preg_replace( '/\s+/', '-', $title );
$title = preg_replace( '|-+|', '-', $title );
$title = trim( $title, '-' );
* Ensures a string is a valid SQL 'order by' clause.
* Accepts one or more columns, with or without a sort order (ASC / DESC).
* e.g. 'column_1', 'column_1, column_2', 'column_1 ASC, column_2 DESC' etc.
* @param string $orderby Order by clause to be validated.
* @return string|false Returns $orderby if valid, false otherwise.
function sanitize_sql_orderby( $orderby ) {
if ( preg_match( '/^\s*(([a-z0-9_]+|`[a-z0-9_]+`)(\s+(ASC|DESC))?\s*(,\s*(?=[a-z0-9_`])|$))+$/i', $orderby ) || preg_match( '/^\s*RAND\(\s*\)\s*$/i', $orderby ) ) {
* Sanitizes an HTML classname to ensure it only contains valid characters.
* Strips the string down to A-Z,a-z,0-9,_,-. If this results in an empty
* string then it will return the alternative value supplied.
* @todo Expand to support the full range of CDATA that a class attribute can contain.
* @param string $class The classname to be sanitized
* @param string $fallback Optional. The value to return if the sanitization ends up as an empty string.
* Defaults to an empty string.
* @return string The sanitized value
function sanitize_html_class( $class, $fallback = '' ) {
// Strip out any %-encoded octets.
$sanitized = preg_replace( '|%[a-fA-F0-9][a-fA-F0-9]|', '', $class );
// Limit to A-Z, a-z, 0-9, '_', '-'.
$sanitized = preg_replace( '/[^A-Za-z0-9_-]/', '', $sanitized );
if ( '' === $sanitized && $fallback ) {
return sanitize_html_class( $fallback );
* Filters a sanitized HTML class string.
* @param string $sanitized The sanitized HTML class.
* @param string $class HTML class before sanitization.
* @param string $fallback The fallback string.
return apply_filters( 'sanitize_html_class', $sanitized, $class, $fallback );
* Strips out all characters not allowed in a locale name.
* @param string $locale_name The locale name to be sanitized.
* @return string The sanitized value.
function sanitize_locale_name( $locale_name ) {
// Limit to A-Z, a-z, 0-9, '_', '-'.
$sanitized = preg_replace( '/[^A-Za-z0-9_-]/', '', $locale_name );
* Filters a sanitized locale name string.
* @param string $sanitized The sanitized locale name.
* @param string $locale_name The locale name before sanitization.
return apply_filters( 'sanitize_locale_name', $sanitized, $locale_name );
* Converts lone & characters into `&` (a.k.a. `&`)
* @param string $content String of characters to be converted.
* @param string $deprecated Not used.
* @return string Converted string.
function convert_chars( $content, $deprecated = '' ) {
if ( ! empty( $deprecated ) ) {
_deprecated_argument( __FUNCTION__, '0.71' );
if ( strpos( $content, '&' ) !== false ) {
$content = preg_replace( '/&([^#])(?![a-z1-4]{1,8};)/i', '&$1', $content );
* Converts invalid Unicode references range to valid range.
* @param string $content String with entities that need converting.
* @return string Converted string.
function convert_invalid_entities( $content ) {
$wp_htmltranswinuni = array(
'€' => '€', // The Euro sign.
'‚' => '‚', // These are Windows CP1252 specific characters.
'ƒ' => 'ƒ', // They would look weird on non-Windows browsers.
if ( strpos( $content, '' ) !== false ) {
$content = strtr( $content, $wp_htmltranswinuni );
* Balances tags if forced to, or if the 'use_balanceTags' option is set to true.
* @param string $text Text to be balanced
* @param bool $force If true, forces balancing, ignoring the value of the option. Default false.
* @return string Balanced text
function balanceTags( $text, $force = false ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid
if ( $force || (int) get_option( 'use_balanceTags' ) === 1 ) {
return force_balance_tags( $text );
* Balances tags of string using a modified stack.
* @since 5.3.0 Improve accuracy and add support for custom element tags.
* @author Leonard Lin <leonard@acm.org>
* @copyright November 4, 2001
* @todo Make better - change loop condition to $text in 1.2
* @internal Modified by Scott Reilly (coffee2code) 02 Aug 2004
* 1.1 Fixed handling of append/stack pop order of end text