From fe742b417f305fa4fc021c8dbe75508e76e7e73f Mon Sep 17 00:00:00 2001 From: Ryan Boren Date: Fri, 29 Jul 2011 20:43:45 +0000 Subject: [PATCH] Better double encoding handling in _wp_special_chars(). Props miqrogroove. git-svn-id: https://develop.svn.wordpress.org/trunk@18485 602fd350-edb4-49c9-b593-d223f7449a82 --- wp-includes/formatting.php | 44 +++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/wp-includes/formatting.php b/wp-includes/formatting.php index f6a9d6a0b1..1632cf8027 100644 --- a/wp-includes/formatting.php +++ b/wp-includes/formatting.php @@ -294,34 +294,31 @@ function seems_utf8($str) { function _wp_specialchars( $string, $quote_style = ENT_NOQUOTES, $charset = false, $double_encode = false ) { $string = (string) $string; - if ( 0 === strlen( $string ) ) { + if ( 0 === strlen( $string ) ) return ''; - } // Don't bother if there are no specialchars - saves some processing - if ( !preg_match( '/[&<>"\']/', $string ) ) { + 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 ) ) { + if ( empty( $quote_style ) ) $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; - } // Store the site charset as a static to avoid multiple calls to wp_load_alloptions() - if ( !$charset ) { + if ( ! $charset ) { static $_charset; - if ( !isset( $_charset ) ) { + if ( ! isset( $_charset ) ) { $alloptions = wp_load_alloptions(); $_charset = isset( $alloptions['blog_charset'] ) ? $alloptions['blog_charset'] : ''; } $charset = $_charset; } - if ( in_array( $charset, array( 'utf8', 'utf-8', 'UTF8' ) ) ) { + + if ( in_array( $charset, array( 'utf8', 'utf-8', 'UTF8' ) ) ) $charset = 'UTF-8'; - } $_quote_style = $quote_style; @@ -333,28 +330,27 @@ function _wp_specialchars( $string, $quote_style = ENT_NOQUOTES, $charset = fals } // Handle double encoding ourselves - if ( !$double_encode ) { + if ( $double_encode ) { + $string = @htmlspecialchars( $string, $quote_style, $charset ); + } else { + // Decode & into & $string = wp_specialchars_decode( $string, $_quote_style ); - /* Critical */ - // The previous line decodes &phrase; into &phrase; We must guarantee that &phrase; is valid before proceeding. - $string = wp_kses_normalize_entities($string); + // Guarantee every &entity; is valid or re-encode the & + $string = wp_kses_normalize_entities( $string ); - // Now proceed with custom double-encoding silliness - $string = preg_replace( '/&(#?x?[0-9a-z]+);/i', '|wp_entity|$1|/wp_entity|', $string ); - } + // Now re-encode everything except &entity; + $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 - if ( !$double_encode ) { - $string = str_replace( array( '|wp_entity|', '|/wp_entity|' ), array( '&', ';' ), $string ); + $string = implode( '', $string ); } // Backwards compatibility - if ( 'single' === $_quote_style ) { + if ( 'single' === $_quote_style ) $string = str_replace( "'", ''', $string ); - } return $string; }