", $pee);
@@ -79,80 +201,345 @@ function wpautop($pee, $br = 1) {
$pee = preg_replace('!
\s*(?' . $allblocks . '[^>]*>)!', "$1", $pee);
$pee = preg_replace('!(?' . $allblocks . '[^>]*>)\s*
!', "$1", $pee);
if ($br) {
- $pee = preg_replace('/<(script|style).*?<\/\\1>/se', 'str_replace("\n", "", "\\0")', $pee);
+ $pee = preg_replace_callback('/<(script|style).*?<\/\\1>/s', '_autop_newline_preservation_helper', $pee);
$pee = preg_replace('|(?)\s*\n|', "
\n", $pee); // optionally make line breaks
$pee = str_replace('', "\n", $pee);
}
$pee = preg_replace('!(?' . $allblocks . '[^>]*>)\s*
!', "$1", $pee);
$pee = preg_replace('!
(\s*?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $pee);
if (strpos($pee, ')(.*?)
!is', 'clean_pre', $pee );
+ $pee = preg_replace_callback('!(]*>)(.*?)
!is', 'clean_pre', $pee );
$pee = preg_replace( "|\n$|", '', $pee );
return $pee;
}
+/**
+ * Newline preservation help function for wpautop
+ *
+ * @since 3.1.0
+ * @access private
+ * @param array $matches preg_replace_callback matches array
+ * @returns string
+ */
+function _autop_newline_preservation_helper( $matches ) {
+ return str_replace("\n", "", $matches[0]);
+}
+
+/**
+ * Don't auto-p wrap shortcodes that stand alone
+ *
+ * Ensures that shortcodes are not wrapped in <>...<
>.
+ *
+ * @since 2.9.0
+ *
+ * @param string $pee The content.
+ * @return string The filtered content.
+ */
+function shortcode_unautop( $pee ) {
+ global $shortcode_tags;
+
+ if ( empty( $shortcode_tags ) || !is_array( $shortcode_tags ) ) {
+ return $pee;
+ }
+
+ $tagregexp = join( '|', array_map( 'preg_quote', array_keys( $shortcode_tags ) ) );
+
+ $pattern =
+ '/'
+ . '' // Opening paragraph
+ . '\\s*+' // Optional leading whitespace
+ . '(' // 1: The shortcode
+ . '\\[' // Opening bracket
+ . "($tagregexp)" // 2: Shortcode name
+ . '\\b' // Word boundary
+ // Unroll the loop: Inside the opening shortcode tag
+ . '[^\\]\\/]*' // Not a closing bracket or forward slash
+ . '(?:'
+ . '\\/(?!\\])' // A forward slash not followed by a closing bracket
+ . '[^\\]\\/]*' // Not a closing bracket or forward slash
+ . ')*?'
+ . '(?:'
+ . '\\/\\]' // Self closing tag and closing bracket
+ . '|'
+ . '\\]' // Closing bracket
+ . '(?:' // Unroll the loop: Optionally, anything between the opening and closing shortcode tags
+ . '[^\\[]*+' // Not an opening bracket
+ . '(?:'
+ . '\\[(?!\\/\\2\\])' // An opening bracket not followed by the closing shortcode tag
+ . '[^\\[]*+' // Not an opening bracket
+ . ')*+'
+ . '\\[\\/\\2\\]' // Closing shortcode tag
+ . ')?'
+ . ')'
+ . ')'
+ . '\\s*+' // optional trailing whitespace
+ . '<\\/p>' // closing paragraph
+ . '/s';
+
+ return preg_replace( $pattern, '$1', $pee );
+}
-function seems_utf8($Str) { # by bmorel at ssi dot fr
- for ($i=0; $i', '>', $text);
- if ( 'double' === $quotes ) {
- $text = str_replace('"', '"', $text);
- } elseif ( 'single' === $quotes ) {
- $text = str_replace("'", ''', $text);
- } elseif ( $quotes ) {
- $text = str_replace('"', '"', $text);
- $text = str_replace("'", ''', $text);
+/**
+ * Converts a number of special characters into their HTML entities.
+ *
+ * Specifically deals with: &, <, >, ", and '.
+ *
+ * $quote_style can be set to ENT_COMPAT to encode " to
+ * ", or ENT_QUOTES to do both. Default is ENT_NOQUOTES where no quotes are encoded.
+ *
+ * @since 1.2.2
+ *
+ * @param string $string The text which is to be encoded.
+ * @param mixed $quote_style Optional. Converts double quotes if set to ENT_COMPAT, both single and double if set to ENT_QUOTES or none if set to ENT_NOQUOTES. Also compatible with old values; converting single quotes if set to 'single', double if set to 'double' or both if otherwise set. Default is ENT_NOQUOTES.
+ * @param string $charset Optional. The character encoding of the string. Default is false.
+ * @param boolean $double_encode Optional. Whether to encode existing html entities. Default is false.
+ * @return string The encoded text with HTML entities.
+ */
+function _wp_specialchars( $string, $quote_style = ENT_NOQUOTES, $charset = false, $double_encode = false ) {
+ $string = (string) $string;
+
+ if ( 0 === strlen( $string ) )
+ return '';
+
+ // Don't bother if there are no specialchars - saves some processing
+ if ( ! preg_match( '/[&<>"\']/', $string ) )
+ return $string;
+
+ // Account for the previous behaviour of the function when the $quote_style is not an accepted value
+ if ( empty( $quote_style ) )
+ $quote_style = ENT_NOQUOTES;
+ elseif ( ! in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) )
+ $quote_style = ENT_QUOTES;
+
+ // Store the site charset as a static to avoid multiple calls to wp_load_alloptions()
+ if ( ! $charset ) {
+ static $_charset;
+ if ( ! isset( $_charset ) ) {
+ $alloptions = wp_load_alloptions();
+ $_charset = isset( $alloptions['blog_charset'] ) ? $alloptions['blog_charset'] : '';
+ }
+ $charset = $_charset;
}
- return $text;
+
+ if ( in_array( $charset, array( 'utf8', 'utf-8', 'UTF8' ) ) )
+ $charset = 'UTF-8';
+
+ $_quote_style = $quote_style;
+
+ if ( $quote_style === 'double' ) {
+ $quote_style = ENT_COMPAT;
+ $_quote_style = ENT_COMPAT;
+ } elseif ( $quote_style === 'single' ) {
+ $quote_style = ENT_NOQUOTES;
+ }
+
+ // Handle double encoding ourselves
+ if ( $double_encode ) {
+ $string = @htmlspecialchars( $string, $quote_style, $charset );
+ } else {
+ // Decode & into &
+ $string = wp_specialchars_decode( $string, $_quote_style );
+
+ // Guarantee every &entity; is valid or re-encode the &
+ $string = wp_kses_normalize_entities( $string );
+
+ // Now re-encode everything except &entity;
+ $string = preg_split( '/(?x?[0-9a-z]+;)/i', $string, -1, PREG_SPLIT_DELIM_CAPTURE );
+
+ for ( $i = 0; $i < count( $string ); $i += 2 )
+ $string[$i] = @htmlspecialchars( $string[$i], $quote_style, $charset );
+
+ $string = implode( '', $string );
+ }
+
+ // Backwards compatibility
+ if ( 'single' === $_quote_style )
+ $string = str_replace( "'", ''', $string );
+
+ return $string;
+}
+
+/**
+ * Converts a number of HTML entities into their special characters.
+ *
+ * Specifically deals with: &, <, >, ", and '.
+ *
+ * $quote_style can be set to ENT_COMPAT to decode " entities,
+ * or ENT_QUOTES to do both " and '. Default is ENT_NOQUOTES where no quotes are decoded.
+ *
+ * @since 2.8
+ *
+ * @param string $string The text which is to be decoded.
+ * @param mixed $quote_style Optional. Converts double quotes if set to ENT_COMPAT, both single and double if set to ENT_QUOTES or none if set to ENT_NOQUOTES. Also compatible with old _wp_specialchars() values; converting single quotes if set to 'single', double if set to 'double' or both if otherwise set. Default is ENT_NOQUOTES.
+ * @return string The decoded text without HTML entities.
+ */
+function wp_specialchars_decode( $string, $quote_style = ENT_NOQUOTES ) {
+ $string = (string) $string;
+
+ if ( 0 === strlen( $string ) ) {
+ return '';
+ }
+
+ // Don't bother if there are no entities - saves a lot of processing
+ if ( strpos( $string, '&' ) === false ) {
+ return $string;
+ }
+
+ // Match the previous behaviour of _wp_specialchars() when the $quote_style is not an accepted value
+ if ( empty( $quote_style ) ) {
+ $quote_style = ENT_NOQUOTES;
+ } elseif ( !in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) ) {
+ $quote_style = ENT_QUOTES;
+ }
+
+ // More complete than get_html_translation_table( HTML_SPECIALCHARS )
+ $single = array( ''' => '\'', ''' => '\'' );
+ $single_preg = array( '/*39;/' => ''', '/*27;/i' => ''' );
+ $double = array( '"' => '"', '"' => '"', '"' => '"' );
+ $double_preg = array( '/*34;/' => '"', '/*22;/i' => '"' );
+ $others = array( '<' => '<', '<' => '<', '>' => '>', '>' => '>', '&' => '&', '&' => '&', '&' => '&' );
+ $others_preg = array( '/*60;/' => '<', '/*62;/' => '>', '/*38;/' => '&', '/*26;/i' => '&' );
+
+ if ( $quote_style === ENT_QUOTES ) {
+ $translation = array_merge( $single, $double, $others );
+ $translation_preg = array_merge( $single_preg, $double_preg, $others_preg );
+ } elseif ( $quote_style === ENT_COMPAT || $quote_style === 'double' ) {
+ $translation = array_merge( $double, $others );
+ $translation_preg = array_merge( $double_preg, $others_preg );
+ } elseif ( $quote_style === 'single' ) {
+ $translation = array_merge( $single, $others );
+ $translation_preg = array_merge( $single_preg, $others_preg );
+ } elseif ( $quote_style === ENT_NOQUOTES ) {
+ $translation = $others;
+ $translation_preg = $others_preg;
+ }
+
+ // Remove zero padding on numeric entities
+ $string = preg_replace( array_keys( $translation_preg ), array_values( $translation_preg ), $string );
+
+ // Replace characters according to translation table
+ return strtr( $string, $translation );
}
+/**
+ * Checks for invalid UTF8 in a string.
+ *
+ * @since 2.8
+ *
+ * @param string $string The text which is to be checked.
+ * @param boolean $strip Optional. Whether to attempt to strip out invalid UTF8. Default is false.
+ * @return string The checked text.
+ */
+function wp_check_invalid_utf8( $string, $strip = false ) {
+ $string = (string) $string;
+
+ if ( 0 === strlen( $string ) ) {
+ return '';
+ }
+
+ // Store the site charset as a static to avoid multiple calls to get_option()
+ static $is_utf8;
+ if ( !isset( $is_utf8 ) ) {
+ $is_utf8 = in_array( get_option( 'blog_charset' ), array( 'utf8', 'utf-8', 'UTF8', 'UTF-8' ) );
+ }
+ if ( !$is_utf8 ) {
+ return $string;
+ }
+
+ // Check for support for utf8 in the installed PCRE library once and store the result in a static
+ static $utf8_pcre;
+ if ( !isset( $utf8_pcre ) ) {
+ $utf8_pcre = @preg_match( '/^./u', 'a' );
+ }
+ // We can't demand utf8 in the PCRE installation, so just return the string in those cases
+ if ( !$utf8_pcre ) {
+ return $string;
+ }
+
+ // preg_match fails when it encounters invalid UTF8 in $string
+ if ( 1 === @preg_match( '/^./us', $string ) ) {
+ return $string;
+ }
+
+ // Attempt to strip the bad chars if requested (not recommended)
+ if ( $strip && function_exists( 'iconv' ) ) {
+ return iconv( 'utf-8', 'utf-8', $string );
+ }
+
+ return '';
+}
+
+/**
+ * Encode the Unicode values to be used in the URI.
+ *
+ * @since 1.5.0
+ *
+ * @param string $utf8_string
+ * @param int $length Max length of the string
+ * @return string String with Unicode encoded for URI.
+ */
function utf8_uri_encode( $utf8_string, $length = 0 ) {
$unicode = '';
$values = array();
$num_octets = 1;
+ $unicode_length = 0;
- for ($i = 0; $i < strlen( $utf8_string ); $i++ ) {
+ $string_length = strlen( $utf8_string );
+ for ($i = 0; $i < $string_length; $i++ ) {
$value = ord( $utf8_string[ $i ] );
if ( $value < 128 ) {
- if ( $length && ( strlen($unicode) + 1 > $length ) )
+ if ( $length && ( $unicode_length >= $length ) )
break;
$unicode .= chr($value);
+ $unicode_length++;
} else {
if ( count( $values ) == 0 ) $num_octets = ( $value < 224 ) ? 2 : 3;
$values[] = $value;
- if ( $length && ( (strlen($unicode) + ($num_octets * 3)) > $length ) )
+ if ( $length && ( $unicode_length + ($num_octets * 3) ) > $length )
break;
if ( count( $values ) == $num_octets ) {
if ($num_octets == 3) {
$unicode .= '%' . dechex($values[0]) . '%' . dechex($values[1]) . '%' . dechex($values[2]);
+ $unicode_length += 9;
} else {
$unicode .= '%' . dechex($values[0]) . '%' . dechex($values[1]);
+ $unicode_length += 6;
}
$values = array();
@@ -164,6 +551,16 @@ function utf8_uri_encode( $utf8_string, $length = 0 ) {
return $unicode;
}
+/**
+ * Converts all accent characters to ASCII characters.
+ *
+ * If there are no accent characters, then the string given is just returned.
+ *
+ * @since 1.2.1
+ *
+ * @param string $string Text that might have accent characters
+ * @return string Filtered string with replaced "nice" characters.
+ */
function remove_accents($string) {
if ( !preg_match('/[\x80-\xff]/', $string) )
return $string;
@@ -171,34 +568,38 @@ function remove_accents($string) {
if (seems_utf8($string)) {
$chars = array(
// Decompositions for Latin-1 Supplement
+ chr(194).chr(170) => 'a', chr(194).chr(186) => 'o',
chr(195).chr(128) => 'A', chr(195).chr(129) => 'A',
chr(195).chr(130) => 'A', chr(195).chr(131) => 'A',
chr(195).chr(132) => 'A', chr(195).chr(133) => 'A',
- chr(195).chr(135) => 'C', chr(195).chr(136) => 'E',
- chr(195).chr(137) => 'E', chr(195).chr(138) => 'E',
- chr(195).chr(139) => 'E', chr(195).chr(140) => 'I',
- chr(195).chr(141) => 'I', chr(195).chr(142) => 'I',
- chr(195).chr(143) => 'I', chr(195).chr(145) => 'N',
+ chr(195).chr(134) => 'AE',chr(195).chr(135) => 'C',
+ chr(195).chr(136) => 'E', chr(195).chr(137) => 'E',
+ chr(195).chr(138) => 'E', chr(195).chr(139) => 'E',
+ chr(195).chr(140) => 'I', chr(195).chr(141) => 'I',
+ chr(195).chr(142) => 'I', chr(195).chr(143) => 'I',
+ chr(195).chr(144) => 'D', chr(195).chr(145) => 'N',
chr(195).chr(146) => 'O', chr(195).chr(147) => 'O',
chr(195).chr(148) => 'O', chr(195).chr(149) => 'O',
chr(195).chr(150) => 'O', chr(195).chr(153) => 'U',
chr(195).chr(154) => 'U', chr(195).chr(155) => 'U',
chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y',
- chr(195).chr(159) => 's', chr(195).chr(160) => 'a',
- chr(195).chr(161) => 'a', chr(195).chr(162) => 'a',
- chr(195).chr(163) => 'a', chr(195).chr(164) => 'a',
- chr(195).chr(165) => 'a', chr(195).chr(167) => 'c',
+ chr(195).chr(158) => 'TH',chr(195).chr(159) => 's',
+ chr(195).chr(160) => 'a', chr(195).chr(161) => 'a',
+ chr(195).chr(162) => 'a', chr(195).chr(163) => 'a',
+ chr(195).chr(164) => 'a', chr(195).chr(165) => 'a',
+ chr(195).chr(166) => 'ae',chr(195).chr(167) => 'c',
chr(195).chr(168) => 'e', chr(195).chr(169) => 'e',
chr(195).chr(170) => 'e', chr(195).chr(171) => 'e',
chr(195).chr(172) => 'i', chr(195).chr(173) => 'i',
chr(195).chr(174) => 'i', chr(195).chr(175) => 'i',
- chr(195).chr(177) => 'n', chr(195).chr(178) => 'o',
- chr(195).chr(179) => 'o', chr(195).chr(180) => 'o',
- chr(195).chr(181) => 'o', chr(195).chr(182) => 'o',
- chr(195).chr(182) => 'o', chr(195).chr(185) => 'u',
- chr(195).chr(186) => 'u', chr(195).chr(187) => 'u',
- chr(195).chr(188) => 'u', chr(195).chr(189) => 'y',
- chr(195).chr(191) => 'y',
+ chr(195).chr(176) => 'd', chr(195).chr(177) => 'n',
+ chr(195).chr(178) => 'o', chr(195).chr(179) => 'o',
+ chr(195).chr(180) => 'o', chr(195).chr(181) => 'o',
+ chr(195).chr(182) => 'o', chr(195).chr(184) => 'o',
+ chr(195).chr(185) => 'u', chr(195).chr(186) => 'u',
+ chr(195).chr(187) => 'u', chr(195).chr(188) => 'u',
+ chr(195).chr(189) => 'y', chr(195).chr(190) => 'th',
+ chr(195).chr(191) => 'y', chr(195).chr(152) => 'O',
// Decompositions for Latin Extended-A
chr(196).chr(128) => 'A', chr(196).chr(129) => 'a',
chr(196).chr(130) => 'A', chr(196).chr(131) => 'a',
@@ -264,6 +665,9 @@ function remove_accents($string) {
chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z',
chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z',
chr(197).chr(190) => 'z', chr(197).chr(191) => 's',
+ // Decompositions for Latin Extended-B
+ chr(200).chr(152) => 'S', chr(200).chr(153) => 's',
+ chr(200).chr(154) => 'T', chr(200).chr(155) => 't',
// Euro Sign
chr(226).chr(130).chr(172) => 'E',
// GBP (Pound) Sign
@@ -294,43 +698,161 @@ function remove_accents($string) {
return $string;
}
-function sanitize_file_name( $name ) { // Like sanitize_title, but with periods
- $name = strtolower( $name );
- $name = preg_replace('/&.+?;/', '', $name); // kill entities
- $name = str_replace( '_', '-', $name );
- $name = preg_replace('/[^a-z0-9\s-.]/', '', $name);
- $name = preg_replace('/\s+/', '-', $name);
- $name = preg_replace('|-+|', '-', $name);
- $name = trim($name, '-');
- return $name;
+/**
+ * Sanitizes a filename replacing whitespace with dashes
+ *
+ * Removes special characters that are illegal in filenames on certain
+ * operating systems and special characters requiring special escaping
+ * to manipulate at the command line. Replaces spaces and consecutive
+ * dashes with a single dash. Trim period, dash and underscore from beginning
+ * and end of filename.
+ *
+ * @since 2.1.0
+ *
+ * @param string $filename The filename to be sanitized
+ * @return string The sanitized filename
+ */
+function sanitize_file_name( $filename ) {
+ $filename_raw = $filename;
+ $special_chars = array("?", "[", "]", "/", "\\", "=", "<", ">", ":", ";", ",", "'", "\"", "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}", chr(0));
+ $special_chars = apply_filters('sanitize_file_name_chars', $special_chars, $filename_raw);
+ $filename = str_replace($special_chars, '', $filename);
+ $filename = preg_replace('/[\s-]+/', '-', $filename);
+ $filename = trim($filename, '.-_');
+
+ // Split the filename into a base and extension[s]
+ $parts = explode('.', $filename);
+
+ // Return if only one extension
+ if ( count($parts) <= 2 )
+ 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. Munge them with a trailing underscore if they are a 2 - 5 character
+ // long alpha string not in the extension whitelist.
+ foreach ( (array) $parts as $part) {
+ $filename .= '.' . $part;
+
+ if ( preg_match("/^[a-zA-Z]{2,5}\d?$/", $part) ) {
+ $allowed = false;
+ foreach ( $mimes as $ext_preg => $mime_match ) {
+ $ext_preg = '!^(' . $ext_preg . ')$!i';
+ if ( preg_match( $ext_preg, $part ) ) {
+ $allowed = true;
+ break;
+ }
+ }
+ if ( !$allowed )
+ $filename .= '_';
+ }
+ }
+ $filename .= '.' . $extension;
+
+ return apply_filters('sanitize_file_name', $filename, $filename_raw);
}
+/**
+ * Sanitize 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 'sanitize_user' filter.
+ *
+ * @since 2.0.0
+ * @uses apply_filters() Calls 'sanitize_user' hook on username, raw username,
+ * and $strict parameter.
+ *
+ * @param string $username The username to be sanitized.
+ * @param bool $strict If set limits $username to specific characters. Default false.
+ * @return string The sanitized username, after passing through filters.
+ */
function sanitize_user( $username, $strict = false ) {
$raw_username = $username;
- $username = strip_tags($username);
+ $username = wp_strip_all_tags( $username );
+ $username = remove_accents( $username );
// Kill octets
- $username = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|', '', $username);
- $username = preg_replace('/&.+?;/', '', $username); // Kill entities
+ $username = preg_replace( '|%([a-fA-F0-9][a-fA-F0-9])|', '', $username );
+ $username = preg_replace( '/&.+?;/', '', $username ); // Kill entities
// If strict, reduce to ASCII for max portability.
if ( $strict )
- $username = preg_replace('|[^a-z0-9 _.\-@]|i', '', $username);
+ $username = preg_replace( '|[^a-z0-9 _.\-@]|i', '', $username );
- return apply_filters('sanitize_user', $username, $raw_username, $strict);
+ $username = trim( $username );
+ // Consolidate contiguous whitespace
+ $username = preg_replace( '|\s+|', ' ', $username );
+
+ return apply_filters( 'sanitize_user', $username, $raw_username, $strict );
}
-function sanitize_title($title, $fallback_title = '') {
- $title = strip_tags($title);
- $title = apply_filters('sanitize_title', $title);
+/**
+ * Sanitize a string key.
+ *
+ * Keys are used as internal identifiers. Lowercase alphanumeric characters, dashes and underscores are allowed.
+ *
+ * @since 3.0.0
+ *
+ * @param string $key String key
+ * @return string Sanitized key
+ */
+function sanitize_key( $key ) {
+ $raw_key = $key;
+ $key = strtolower( $key );
+ $key = preg_replace( '/[^a-z0-9_\-]/', '', $key );
+ return apply_filters( 'sanitize_key', $key, $raw_key );
+}
- if (empty($title)) {
+/**
+ * Sanitizes title or use fallback title.
+ *
+ * Specifically, HTML and PHP tags are stripped. Further actions can be added
+ * via the plugin API. If $title is empty and $fallback_title is set, the latter
+ * will be used.
+ *
+ * @since 1.0.0
+ *
+ * @param string $title The string to be sanitized.
+ * @param string $fallback_title Optional. A title to use if $title is empty.
+ * @param string $context Optional. The operation for which the string is sanitized
+ * @return string The sanitized string.
+ */
+function sanitize_title($title, $fallback_title = '', $context = 'save') {
+ $raw_title = $title;
+
+ if ( 'save' == $context )
+ $title = remove_accents($title);
+
+ $title = apply_filters('sanitize_title', $title, $raw_title, $context);
+
+ if ( '' === $title || false === $title )
$title = $fallback_title;
- }
return $title;
}
-function sanitize_title_with_dashes($title) {
+function sanitize_title_for_query($title) {
+ return sanitize_title($title, '', 'query');
+}
+
+/**
+ * Sanitizes title, replacing whitespace and a few other characters with dashes.
+ *
+ * Limits the output to alphanumeric characters, underscore (_) and dash (-).
+ * Whitespace becomes a dash.
+ *
+ * @since 1.2.0
+ *
+ * @param string $title The title to be sanitized.
+ * @param string $raw_title Optional. Not used.
+ * @param string $context Optional. The operation for which the string is sanitized.
+ * @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);
@@ -339,7 +861,6 @@ function sanitize_title_with_dashes($title) {
// Restore octets.
$title = preg_replace('|---([a-fA-F0-9][a-fA-F0-9])---|', '%$1', $title);
- $title = remove_accents($title);
if (seems_utf8($title)) {
if (function_exists('mb_strtolower')) {
$title = mb_strtolower($title, 'UTF-8');
@@ -349,6 +870,21 @@ function sanitize_title_with_dashes($title) {
$title = strtolower($title);
$title = preg_replace('/&.+?;/', '', $title); // kill entities
+ $title = str_replace('.', '-', $title);
+
+ if ( 'save' == $context ) {
+ // nbsp, ndash and mdash
+ $title = str_replace( array( '%c2%a0', '%e2%80%93', '%e2%80%94' ), '-', $title );
+ // iexcl and iquest
+ $title = str_replace( array( '%c2%a1', '%c2%bf' ), '', $title );
+ // angle quotes
+ $title = str_replace( array( '%c2%ab', '%c2%bb', '%e2%80%b9', '%e2%80%ba' ), '', $title );
+ // curly quotes
+ $title = str_replace( array( '%e2%80%98', '%e2%80%99', '%e2%80%9c', '%e2%80%9d' ), '', $title );
+ // copy, reg, deg, hellip and trade
+ $title = str_replace( array( '%c2%a9', '%c2%ae', '%c2%b0', '%e2%80%a6', '%e2%84%a2' ), '', $title );
+ }
+
$title = preg_replace('/[^%a-z0-9 _-]/', '', $title);
$title = preg_replace('/\s+/', '-', $title);
$title = preg_replace('|-+|', '-', $title);
@@ -357,7 +893,69 @@ function sanitize_title_with_dashes($title) {
return $title;
}
-function convert_chars($content, $flag = 'obsolete') {
+/**
+ * Ensures a string is a valid SQL order by clause.
+ *
+ * Accepts one or more columns, with or without ASC/DESC, and also accepts
+ * RAND().
+ *
+ * @since 2.5.1
+ *
+ * @param string $orderby Order by string to be checked.
+ * @return string|false Returns the order by clause if it is a match, false otherwise.
+ */
+function sanitize_sql_orderby( $orderby ){
+ preg_match('/^\s*([a-z0-9_]+(\s+(ASC|DESC))?(\s*,\s*|\s*$))+|^\s*RAND\(\s*\)\s*$/i', $orderby, $obmatches);
+ if ( !$obmatches )
+ return false;
+ return $orderby;
+}
+
+/**
+ * Santizes a 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.
+ *
+ * @since 2.8.0
+ *
+ * @param string $class The classname to be sanitized
+ * @param string $fallback Optional. The value to return if the sanitization end's 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 )
+ $sanitized = $fallback;
+
+ return apply_filters( 'sanitize_html_class', $sanitized, $class, $fallback );
+}
+
+/**
+ * Converts a number of characters from a string.
+ *
+ * Metadata tags <> and <> are removed, <
> and <
> are
+ * converted into correct XHTML and Unicode characters are converted to the
+ * valid range.
+ *
+ * @since 0.71
+ *
+ * @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' );
+
// Translation of invalid Unicode references range to valid range
$wp_htmltranswinuni = array(
'' => '€', // the Euro sign
@@ -411,80 +1009,84 @@ function convert_chars($content, $flag = 'obsolete') {
return $content;
}
-function funky_javascript_fix($text) {
- // Fixes for browsers' javascript bugs
- global $is_macIE, $is_winIE;
-
- if ( $is_winIE || $is_macIE )
- $text = preg_replace("/\%u([0-9A-F]{4,4})/e", "''.base_convert('\\1',16,10).';'", $text);
-
- return $text;
-}
-
+/**
+ * Will only balance the tags if forced to and the option is set to balance tags.
+ *
+ * The option 'use_balanceTags' is used for whether the tags will be balanced.
+ * Both the $force parameter and 'use_balanceTags' option will have to be true
+ * before the tags will be balanced.
+ *
+ * @since 0.71
+ *
+ * @param string $text Text to be balanced
+ * @param bool $force Forces balancing, ignoring the value of the option. Default false.
+ * @return string Balanced text
+ */
function balanceTags( $text, $force = false ) {
if ( !$force && get_option('use_balanceTags') == 0 )
return $text;
return force_balance_tags( $text );
}
-/*
- force_balance_tags
-
- Balances Tags of string using a modified stack.
-
- @param text Text to be balanced
- @param force Forces balancing, ignoring the value of the option
- @return Returns balanced text
- @author Leonard Lin (leonard@acm.org)
- @version v1.1
- @date November 4, 2001
- @license GPL v2.0
- @notes
- @changelog
- --- Modified by Scott Reilly (coffee2code) 02 Aug 2004
- 1.2 ***TODO*** Make better - change loop condition to $text
- 1.1 Fixed handling of append/stack pop order of end text
- Added Cleaning Hooks
- 1.0 First Version
-*/
+/**
+ * Balances tags of string using a modified stack.
+ *
+ * @since 2.0.4
+ *
+ * @author Leonard Lin
+ * @license GPL
+ * @copyright November 4, 2001
+ * @version 1.1
+ * @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
+ * Added Cleaning Hooks
+ * 1.0 First Version
+ *
+ * @param string $text Text to be balanced.
+ * @return string Balanced text.
+ */
function force_balance_tags( $text ) {
- $tagstack = array(); $stacksize = 0; $tagqueue = ''; $newtext = '';
- $single_tags = array('br', 'hr', 'img', 'input'); //Known single-entity/self-closing tags
- $nestable_tags = array('blockquote', 'div', 'span'); //Tags that can be immediately nested within themselves
-
- # WP bug fix for comments - in case you REALLY meant to type '< !--'
+ $tagstack = array();
+ $stacksize = 0;
+ $tagqueue = '';
+ $newtext = '';
+ $single_tags = array( 'br', 'hr', 'img', 'input' ); // Known single-entity/self-closing tags
+ $nestable_tags = array( 'blockquote', 'div', 'span', 'q' ); // Tags that can be immediately nested within themselves
+
+ // WP bug fix for comments - in case you REALLY meant to type '< !--'
$text = str_replace('< !--', '< !--', $text);
- # WP bug fix for LOVE <3 (and other situations with '<' before a number)
+ // WP bug fix for LOVE <3 (and other situations with '<' before a number)
$text = preg_replace('#<([0-9]{1})#', '<$1', $text);
- while (preg_match("/<(\/?\w*)\s*([^>]*)>/",$text,$regex)) {
+ while ( preg_match("/<(\/?[\w:]*)\s*([^>]*)>/", $text, $regex) ) {
$newtext .= $tagqueue;
- $i = strpos($text,$regex[0]);
+ $i = strpos($text, $regex[0]);
$l = strlen($regex[0]);
// clear the shifter
$tagqueue = '';
// Pop or Push
- if ($regex[1][0] == "/") { // End Tag
+ if ( isset($regex[1][0]) && '/' == $regex[1][0] ) { // End Tag
$tag = strtolower(substr($regex[1],1));
// if too many closing tags
- if($stacksize <= 0) {
+ if( $stacksize <= 0 ) {
$tag = '';
- //or close to be safe $tag = '/' . $tag;
+ // or close to be safe $tag = '/' . $tag;
}
// if stacktop value = tag close value then pop
- else if ($tagstack[$stacksize - 1] == $tag) { // found closing tag
+ else if ( $tagstack[$stacksize - 1] == $tag ) { // found closing tag
$tag = '' . $tag . '>'; // Close Tag
// Pop
- array_pop ($tagstack);
+ array_pop( $tagstack );
$stacksize--;
} else { // closing tag not at top, search for it
- for ($j=$stacksize-1;$j>=0;$j--) {
- if ($tagstack[$j] == $tag) {
+ for ( $j = $stacksize-1; $j >= 0; $j-- ) {
+ if ( $tagstack[$j] == $tag ) {
// add tag to tagqueue
- for ($k=$stacksize-1;$k>=$j;$k--){
- $tagqueue .= '' . array_pop ($tagstack) . '>';
+ for ( $k = $stacksize-1; $k >= $j; $k--) {
+ $tagqueue .= '' . array_pop( $tagstack ) . '>';
$stacksize--;
}
break;
@@ -498,14 +1100,15 @@ function force_balance_tags( $text ) {
// Tag Cleaning
// If self-closing or '', don't do anything.
- if((substr($regex[2],-1) == '/') || ($tag == '')) {
+ if ( substr($regex[2],-1) == '/' || $tag == '' ) {
+ // do nothing
}
// ElseIf it's a known single-entity tag but it doesn't close itself, do so
elseif ( in_array($tag, $single_tags) ) {
$regex[2] .= '/';
} else { // Push the tag onto the stack
// If the top of the stack is the same as the tag we want to push, close previous tag
- if (($stacksize > 0) && !in_array($tag, $nestable_tags) && ($tagstack[$stacksize - 1] == $tag)) {
+ if ( $stacksize > 0 && !in_array($tag, $nestable_tags) && $tagstack[$stacksize - 1] == $tag ) {
$tagqueue = '' . array_pop ($tagstack) . '>';
$stacksize--;
}
@@ -514,18 +1117,18 @@ function force_balance_tags( $text ) {
// Attributes
$attributes = $regex[2];
- if($attributes) {
+ if( !empty($attributes) )
$attributes = ' '.$attributes;
- }
- $tag = '<'.$tag.$attributes.'>';
+
+ $tag = '<' . $tag . $attributes . '>';
//If already queuing a close tag, then put this tag on, too
- if ($tagqueue) {
+ if ( !empty($tagqueue) ) {
$tagqueue .= $tag;
$tag = '';
}
}
- $newtext .= substr($text,0,$i) . $tag;
- $text = substr($text,$i+$l);
+ $newtext .= substr($text, 0, $i) . $tag;
+ $text = substr($text, $i + $l);
}
// Clear Tag Queue
@@ -535,9 +1138,8 @@ function force_balance_tags( $text ) {
$newtext .= $text;
// Empty Stack
- while($x = array_pop($tagstack)) {
+ while( $x = array_pop($tagstack) )
$newtext .= '' . $x . '>'; // Add remaining tags to close
- }
// WP fix for the bug with HTML comments
$newtext = str_replace("< !--","