Better double encoding handling in _wp_special_chars(). Props miqrogroove.

git-svn-id: http://svn.automattic.com/wordpress/trunk@18485 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
ryan 2011-07-29 20:43:45 +00:00
parent 34467767ff
commit 6c39a6f769
1 changed files with 20 additions and 24 deletions

View File

@ -294,34 +294,31 @@ function seems_utf8($str) {
function _wp_specialchars( $string, $quote_style = ENT_NOQUOTES, $charset = false, $double_encode = false ) { function _wp_specialchars( $string, $quote_style = ENT_NOQUOTES, $charset = false, $double_encode = false ) {
$string = (string) $string; $string = (string) $string;
if ( 0 === strlen( $string ) ) { if ( 0 === strlen( $string ) )
return ''; return '';
}
// Don't bother if there are no specialchars - saves some processing // Don't bother if there are no specialchars - saves some processing
if ( !preg_match( '/[&<>"\']/', $string ) ) { if ( ! preg_match( '/[&<>"\']/', $string ) )
return $string; return $string;
}
// Account for the previous behaviour of the function when the $quote_style is not an accepted value // Account for the previous behaviour of the function when the $quote_style is not an accepted value
if ( empty( $quote_style ) ) { if ( empty( $quote_style ) )
$quote_style = ENT_NOQUOTES; $quote_style = ENT_NOQUOTES;
} elseif ( !in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) ) { elseif ( ! in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) )
$quote_style = ENT_QUOTES; $quote_style = ENT_QUOTES;
}
// Store the site charset as a static to avoid multiple calls to wp_load_alloptions() // Store the site charset as a static to avoid multiple calls to wp_load_alloptions()
if ( !$charset ) { if ( ! $charset ) {
static $_charset; static $_charset;
if ( !isset( $_charset ) ) { if ( ! isset( $_charset ) ) {
$alloptions = wp_load_alloptions(); $alloptions = wp_load_alloptions();
$_charset = isset( $alloptions['blog_charset'] ) ? $alloptions['blog_charset'] : ''; $_charset = isset( $alloptions['blog_charset'] ) ? $alloptions['blog_charset'] : '';
} }
$charset = $_charset; $charset = $_charset;
} }
if ( in_array( $charset, array( 'utf8', 'utf-8', 'UTF8' ) ) ) {
if ( in_array( $charset, array( 'utf8', 'utf-8', 'UTF8' ) ) )
$charset = 'UTF-8'; $charset = 'UTF-8';
}
$_quote_style = $quote_style; $_quote_style = $quote_style;
@ -333,28 +330,27 @@ function _wp_specialchars( $string, $quote_style = ENT_NOQUOTES, $charset = fals
} }
// Handle double encoding ourselves // Handle double encoding ourselves
if ( !$double_encode ) { if ( $double_encode ) {
$string = @htmlspecialchars( $string, $quote_style, $charset );
} else {
// Decode &amp; into &
$string = wp_specialchars_decode( $string, $_quote_style ); $string = wp_specialchars_decode( $string, $_quote_style );
/* Critical */ // Guarantee every &entity; is valid or re-encode the &
// The previous line decodes &amp;phrase; into &phrase; We must guarantee that &phrase; is valid before proceeding. $string = wp_kses_normalize_entities( $string );
$string = wp_kses_normalize_entities($string);
// Now proceed with custom double-encoding silliness // Now re-encode everything except &entity;
$string = preg_replace( '/&(#?x?[0-9a-z]+);/i', '|wp_entity|$1|/wp_entity|', $string ); $string = preg_split( '/(&#?x?[0-9a-z]+;)/i', $string, -1, PREG_SPLIT_DELIM_CAPTURE );
}
$string = @htmlspecialchars( $string, $quote_style, $charset ); for ( $i = 0; $i < count( $string ); $i += 2 )
$string[$i] = @htmlspecialchars( $string[$i], $quote_style, $charset );
// Handle double encoding ourselves $string = implode( '', $string );
if ( !$double_encode ) {
$string = str_replace( array( '|wp_entity|', '|/wp_entity|' ), array( '&', ';' ), $string );
} }
// Backwards compatibility // Backwards compatibility
if ( 'single' === $_quote_style ) { if ( 'single' === $_quote_style )
$string = str_replace( "'", '&#039;', $string ); $string = str_replace( "'", '&#039;', $string );
}
return $string; return $string;
} }