Add `wp_json_encode()`, a wrapper for `json_encode()` that ensures everything is converted to UTF-8.

Change all core calls from `json_encode()` to `wp_json_encode()`.

Fixes #28786.


Built from https://develop.svn.wordpress.org/trunk@30055


git-svn-id: http://core.svn.wordpress.org/trunk@30055 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Gary Pendergast 2014-10-28 18:35:19 +00:00
parent 3d99ef90d6
commit 007ec52958
17 changed files with 153 additions and 40 deletions

View File

@ -274,7 +274,7 @@ do_action( 'customize_controls_print_scripts' );
?> ?>
<script type="text/javascript"> <script type="text/javascript">
var _wpCustomizeSettings = <?php echo json_encode( $settings ); ?>; var _wpCustomizeSettings = <?php echo wp_json_encode( $settings ); ?>;
</script> </script>
</div> </div>
</body> </body>

View File

@ -286,7 +286,7 @@ function wp_ajax_autocomplete_user() {
); );
} }
wp_die( json_encode( $return ) ); wp_die( wp_json_encode( $return ) );
} }
/** /**
@ -1365,7 +1365,7 @@ function wp_ajax_menu_get_metabox() {
$markup = ob_get_clean(); $markup = ob_get_clean();
echo json_encode(array( echo wp_json_encode(array(
'replace-id' => $type . '-' . $item->name, 'replace-id' => $type . '-' . $item->name,
'markup' => $markup, 'markup' => $markup,
)); ));
@ -1394,7 +1394,7 @@ function wp_ajax_wp_link_ajax() {
if ( ! isset( $results ) ) if ( ! isset( $results ) )
wp_die( 0 ); wp_die( 0 );
echo json_encode( $results ); echo wp_json_encode( $results );
echo "\n"; echo "\n";
wp_die(); wp_die();
@ -1840,7 +1840,7 @@ function wp_ajax_upload_attachment() {
if ( isset( $post_data['context'] ) && in_array( $post_data['context'], array( 'custom-header', 'custom-background' ) ) ) { if ( isset( $post_data['context'] ) && in_array( $post_data['context'], array( 'custom-header', 'custom-background' ) ) ) {
$wp_filetype = wp_check_filetype_and_ext( $_FILES['async-upload']['tmp_name'], $_FILES['async-upload']['name'], false ); $wp_filetype = wp_check_filetype_and_ext( $_FILES['async-upload']['tmp_name'], $_FILES['async-upload']['name'], false );
if ( ! wp_match_mime_types( 'image', $wp_filetype['type'] ) ) { if ( ! wp_match_mime_types( 'image', $wp_filetype['type'] ) ) {
echo json_encode( array( echo wp_json_encode( array(
'success' => false, 'success' => false,
'data' => array( 'data' => array(
'message' => __( 'The uploaded file is not a valid image. Please try again.' ), 'message' => __( 'The uploaded file is not a valid image. Please try again.' ),
@ -1855,7 +1855,7 @@ function wp_ajax_upload_attachment() {
$attachment_id = media_handle_upload( 'async-upload', $post_id, $post_data ); $attachment_id = media_handle_upload( 'async-upload', $post_id, $post_data );
if ( is_wp_error( $attachment_id ) ) { if ( is_wp_error( $attachment_id ) ) {
echo json_encode( array( echo wp_json_encode( array(
'success' => false, 'success' => false,
'data' => array( 'data' => array(
'message' => $attachment_id->get_error_message(), 'message' => $attachment_id->get_error_message(),
@ -1877,7 +1877,7 @@ function wp_ajax_upload_attachment() {
if ( ! $attachment = wp_prepare_attachment_for_js( $attachment_id ) ) if ( ! $attachment = wp_prepare_attachment_for_js( $attachment_id ) )
wp_die(); wp_die();
echo json_encode( array( echo wp_json_encode( array(
'success' => true, 'success' => true,
'data' => $attachment, 'data' => $attachment,
) ); ) );
@ -1902,7 +1902,7 @@ function wp_ajax_image_editor() {
switch ( $_POST['do'] ) { switch ( $_POST['do'] ) {
case 'save' : case 'save' :
$msg = wp_save_image($attachment_id); $msg = wp_save_image($attachment_id);
$msg = json_encode($msg); $msg = wp_json_encode($msg);
wp_die( $msg ); wp_die( $msg );
break; break;
case 'scale' : case 'scale' :

View File

@ -1058,7 +1058,7 @@ class WP_List_Table {
$response['total_pages_i18n'] = number_format_i18n( $this->_pagination_args['total_pages'] ); $response['total_pages_i18n'] = number_format_i18n( $this->_pagination_args['total_pages'] );
} }
die( json_encode( $response ) ); die( wp_json_encode( $response ) );
} }
/** /**
@ -1075,6 +1075,6 @@ class WP_List_Table {
) )
); );
printf( "<script type='text/javascript'>list_args = %s;</script>\n", json_encode( $args ) ); printf( "<script type='text/javascript'>list_args = %s;</script>\n", wp_json_encode( $args ) );
} }
} }

View File

@ -273,7 +273,7 @@ class WP_Themes_List_Table extends WP_List_Table {
if ( is_array( $extra_args ) ) if ( is_array( $extra_args ) )
$args = array_merge( $args, $extra_args ); $args = array_merge( $args, $extra_args );
printf( "<script type='text/javascript'>var theme_list_args = %s;</script>\n", json_encode( $args ) ); printf( "<script type='text/javascript'>var theme_list_args = %s;</script>\n", wp_json_encode( $args ) );
parent::_js_vars(); parent::_js_vars();
} }
} }

View File

@ -1826,7 +1826,7 @@ if( !$large_size_w )
$large_size_w = 1024; $large_size_w = 1024;
?> ?>
var resize_height = <?php echo $large_size_h; ?>, resize_width = <?php echo $large_size_w; ?>, var resize_height = <?php echo $large_size_h; ?>, resize_width = <?php echo $large_size_w; ?>,
wpUploaderInit = <?php echo json_encode($plupload_init); ?>; wpUploaderInit = <?php echo wp_json_encode( $plupload_init ); ?>;
</script> </script>
<div id="plupload-upload-ui" class="hide-if-no-js"> <div id="plupload-upload-ui" class="hide-if-no-js">

View File

@ -621,7 +621,7 @@ function admin_color_scheme_picker( $user_id ) {
<div class="color-option <?php echo ( $color == $current_color ) ? 'selected' : ''; ?>"> <div class="color-option <?php echo ( $color == $current_color ) ? 'selected' : ''; ?>">
<input name="admin_color" id="admin_color_<?php echo esc_attr( $color ); ?>" type="radio" value="<?php echo esc_attr( $color ); ?>" class="tog" <?php checked( $color, $current_color ); ?> /> <input name="admin_color" id="admin_color_<?php echo esc_attr( $color ); ?>" type="radio" value="<?php echo esc_attr( $color ); ?>" class="tog" <?php checked( $color, $current_color ); ?> />
<input type="hidden" class="css_url" value="<?php echo esc_url( $color_info->url ); ?>" /> <input type="hidden" class="css_url" value="<?php echo esc_url( $color_info->url ); ?>" />
<input type="hidden" class="icon_colors" value="<?php echo esc_attr( json_encode( array( 'icons' => $color_info->icon_colors ) ) ); ?>" /> <input type="hidden" class="icon_colors" value="<?php echo esc_attr( wp_json_encode( array( 'icons' => $color_info->icon_colors ) ) ); ?>" />
<label for="admin_color_<?php echo esc_attr( $color ); ?>"><?php echo esc_html( $color_info->name ); ?></label> <label for="admin_color_<?php echo esc_attr( $color ); ?>"><?php echo esc_html( $color_info->name ); ?></label>
<table class="color-palette"> <table class="color-palette">
<tr> <tr>
@ -665,7 +665,7 @@ function wp_color_scheme_settings() {
$icon_colors = array( 'base' => '#999', 'focus' => '#2ea2cc', 'current' => '#fff' ); $icon_colors = array( 'base' => '#999', 'focus' => '#2ea2cc', 'current' => '#fff' );
} }
echo '<script type="text/javascript">var _wpColorScheme = ' . json_encode( array( 'icons' => $icon_colors ) ) . ";</script>\n"; echo '<script type="text/javascript">var _wpColorScheme = ' . wp_json_encode( array( 'icons' => $icon_colors ) ) . ";</script>\n";
} }
add_action( 'admin_head', 'wp_color_scheme_settings' ); add_action( 'admin_head', 'wp_color_scheme_settings' );

View File

@ -356,7 +356,7 @@ function _wp_ajax_menu_quick_search( $request = array() ) {
if ( 'markup' == $response_format ) { if ( 'markup' == $response_format ) {
echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', array( get_post( $object_id ) ) ), 0, (object) $args ); echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', array( get_post( $object_id ) ) ), 0, (object) $args );
} elseif ( 'json' == $response_format ) { } elseif ( 'json' == $response_format ) {
echo json_encode( echo wp_json_encode(
array( array(
'ID' => $object_id, 'ID' => $object_id,
'post_title' => get_the_title( $object_id ), 'post_title' => get_the_title( $object_id ),
@ -373,7 +373,7 @@ function _wp_ajax_menu_quick_search( $request = array() ) {
echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', array( get_term( $object_id, $object_type ) ) ), 0, (object) $args ); echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', array( get_term( $object_id, $object_type ) ) ), 0, (object) $args );
} elseif ( 'json' == $response_format ) { } elseif ( 'json' == $response_format ) {
$post_obj = get_term( $object_id, $object_type ); $post_obj = get_term( $object_id, $object_type );
echo json_encode( echo wp_json_encode(
array( array(
'ID' => $object_id, 'ID' => $object_id,
'post_title' => $post_obj->name, 'post_title' => $post_obj->name,
@ -401,7 +401,7 @@ function _wp_ajax_menu_quick_search( $request = array() ) {
$var_by_ref = get_the_ID(); $var_by_ref = get_the_ID();
echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', array( get_post( $var_by_ref ) ) ), 0, (object) $args ); echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', array( get_post( $var_by_ref ) ) ), 0, (object) $args );
} elseif ( 'json' == $response_format ) { } elseif ( 'json' == $response_format ) {
echo json_encode( echo wp_json_encode(
array( array(
'ID' => get_the_ID(), 'ID' => get_the_ID(),
'post_title' => get_the_title(), 'post_title' => get_the_title(),
@ -422,7 +422,7 @@ function _wp_ajax_menu_quick_search( $request = array() ) {
if ( 'markup' == $response_format ) { if ( 'markup' == $response_format ) {
echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', array( $term ) ), 0, (object) $args ); echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', array( $term ) ), 0, (object) $args );
} elseif ( 'json' == $response_format ) { } elseif ( 'json' == $response_format ) {
echo json_encode( echo wp_json_encode(
array( array(
'ID' => $term->term_id, 'ID' => $term->term_id,
'post_title' => $term->name, 'post_title' => $term->name,

View File

@ -1952,7 +1952,7 @@ final class WP_Internal_Pointers {
<script type="text/javascript"> <script type="text/javascript">
//<![CDATA[ //<![CDATA[
(function($){ (function($){
var options = <?php echo json_encode( $args ); ?>, setup; var options = <?php echo wp_json_encode( $args ); ?>, setup;
if ( ! options ) if ( ! options )
return; return;

View File

@ -517,7 +517,7 @@ final class WP_Customize_Manager {
?> ?>
<script type="text/javascript"> <script type="text/javascript">
var _wpCustomizeSettings = <?php echo json_encode( $settings ); ?>; var _wpCustomizeSettings = <?php echo wp_json_encode( $settings ); ?>;
</script> </script>
<?php <?php
} }

View File

@ -740,7 +740,7 @@ final class WP_Customize_Widgets {
$wp_scripts->add_data( $wp_scripts->add_data(
'customize-widgets', 'customize-widgets',
'data', 'data',
sprintf( 'var _wpCustomizeWidgetsSettings = %s;', json_encode( $settings ) ) sprintf( 'var _wpCustomizeWidgetsSettings = %s;', wp_json_encode( $settings ) )
); );
} }
@ -1055,7 +1055,7 @@ final class WP_Customize_Widgets {
?> ?>
<script type="text/javascript"> <script type="text/javascript">
var _wpWidgetCustomizerPreviewSettings = <?php echo json_encode( $settings ); ?>; var _wpWidgetCustomizerPreviewSettings = <?php echo wp_json_encode( $settings ); ?>;
</script> </script>
<?php <?php
} }

View File

@ -500,7 +500,7 @@ final class _WP_Editors {
); );
if ( ! empty( $mce_external_plugins ) ) { if ( ! empty( $mce_external_plugins ) ) {
self::$first_init['external_plugins'] = json_encode( $mce_external_plugins ); self::$first_init['external_plugins'] = wp_json_encode( $mce_external_plugins );
} }
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
@ -986,7 +986,7 @@ final class _WP_Editors {
$mce_translation['_dir'] = 'rtl'; $mce_translation['_dir'] = 'rtl';
} }
return "tinymce.addI18n( '$mce_locale', " . json_encode( $mce_translation ) . ");\n" . return "tinymce.addI18n( '$mce_locale', " . wp_json_encode( $mce_translation ) . ");\n" .
"tinymce.ScriptLoader.markDone( '$baseurl/langs/$mce_locale.js' );\n"; "tinymce.ScriptLoader.markDone( '$baseurl/langs/$mce_locale.js' );\n";
} }

View File

@ -167,7 +167,7 @@ class WP_Scripts extends WP_Dependencies {
$l10n[$key] = html_entity_decode( (string) $value, ENT_QUOTES, 'UTF-8'); $l10n[$key] = html_entity_decode( (string) $value, ENT_QUOTES, 'UTF-8');
} }
$script = "var $object_name = " . json_encode($l10n) . ';'; $script = "var $object_name = " . wp_json_encode( $l10n ) . ';';
if ( !empty($after) ) if ( !empty($after) )
$script .= "\n$after;"; $script .= "\n$after;";

View File

@ -2612,6 +2612,119 @@ function _scalar_wp_die_handler( $message = '' ) {
die(); die();
} }
/**
* Encode a variable into JSON, with some sanity checks
*
* @since 4.1.0
*
* @param mixed $data Variable (usually an array or object) to encode as JSON
* @param int $options Options to be passed to json_encode(). Default 0.
* @param int $depth Maximum depth to walk through $data. Must be greater than 0, default 512.t
*
* @return bool|string The JSON encoded string, or false if it cannot be encoded
*/
function wp_json_encode( $data, $options = 0, $depth = 512 ) {
// json_encode has had extra params added over the years.
// $options was added in 5.3, and $depth in 5.5.
// We need to make sure we call it with the correct arguments.
if ( version_compare( PHP_VERSION, '5.5', '>=' ) ) {
$args = array( $data, $options, $depth );
} else if ( version_compare( PHP_VERSION, '5.3', '>=' ) ) {
$args = array( $data, $options );
} else {
$args = array( $data );
}
$json = call_user_func_array( 'json_encode', $args );
if ( false !== $json ) {
// If json_encode was successful, no need to do more sanity checking
return $json;
}
try {
$args[0] = _wp_json_sanity_check( $data, $depth );
} catch ( Exception $e ) {
return false;
}
return call_user_func_array( 'json_encode', $args );
}
/**
* @ignore
*/
function _wp_json_sanity_check( $data, $depth ) {
if ( $depth < 0 ) {
throw new Exception( 'Reached depth limit' );
}
if ( is_array( $data ) ) {
$output = array();
foreach ( $data as $id => $el ) {
// Don't forget to sanitize the ID!
if ( is_string( $id ) ) {
$clean_id = _wp_json_convert_string( $id );
} else {
$clean_id = $id;
}
// Check the element type, so that we're only recursing if we really have to
if ( is_array( $el ) || is_object( $el ) ) {
$output[ $clean_id ] = _wp_json_sanity_check( $el, $depth - 1 );
} else if ( is_string( $el ) ) {
$output[ $clean_id ] = _wp_json_convert_string( $el );
} else {
$output[ $clean_id ] = $el;
}
}
} else if ( is_object( $data ) ) {
$output = new stdClass;
foreach ( $data as $id => $el ) {
if ( is_string( $id ) ) {
$clean_id = _wp_json_convert_string( $id );
} else {
$clean_id = $id;
}
if ( is_array( $el ) || is_object( $el ) ) {
$output->$clean_id = _wp_json_sanity_check( $el, $depth - 1 );
} else if ( is_string( $el ) ) {
$output->$clean_id = _wp_json_convert_string( $el );
} else {
$output->$clean_id = $el;
}
}
} else if ( is_string( $data ) ) {
return _wp_json_convert_string( $data );
} else {
return $data;
}
return $output;
}
/**
* @ignore
*/
function _wp_json_convert_string( $string ) {
static $use_mb = null;
if ( is_null( $use_mb ) ) {
$use_mb = function_exists( 'mb_convert_encoding' );
}
if ( $use_mb ) {
$encoding = mb_detect_encoding( $string, mb_detect_order(), true );
if ( $encoding ) {
return mb_convert_encoding( $string, 'UTF-8', $encoding );
} else {
return mb_convert_encoding( $string, 'UTF-8', 'UTF-8' );
}
} else {
return wp_check_invalid_utf8( $data, true );
}
}
/** /**
* Send a JSON response back to an Ajax request. * Send a JSON response back to an Ajax request.
* *
@ -2622,7 +2735,7 @@ function _scalar_wp_die_handler( $message = '' ) {
*/ */
function wp_send_json( $response ) { function wp_send_json( $response ) {
@header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) ); @header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
echo json_encode( $response ); echo wp_json_encode( $response );
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) if ( defined( 'DOING_AJAX' ) && DOING_AJAX )
wp_die(); wp_die();
else else

View File

@ -1398,7 +1398,7 @@ function wp_playlist_shortcode( $attr ) {
} }
?></ol> ?></ol>
</noscript> </noscript>
<script type="application/json" class="wp-playlist-script"><?php echo json_encode( $data ) ?></script> <script type="application/json" class="wp-playlist-script"><?php echo wp_json_encode( $data ) ?></script>
</div> </div>
<?php <?php
return ob_get_clean(); return ob_get_clean();
@ -2582,7 +2582,7 @@ function wp_plupload_default_settings() {
'limitExceeded' => is_multisite() && ! is_upload_space_available() 'limitExceeded' => is_multisite() && ! is_upload_space_available()
); );
$script = 'var _wpPluploadSettings = ' . json_encode( $settings ) . ';'; $script = 'var _wpPluploadSettings = ' . wp_json_encode( $settings ) . ';';
if ( $data ) if ( $data )
$script = "$data\n$script"; $script = "$data\n$script";

View File

@ -1939,7 +1939,7 @@ function _wp_customize_loader_settings() {
), ),
); );
$script = 'var _wpCustomizeLoaderSettings = ' . json_encode( $settings ) . ';'; $script = 'var _wpCustomizeLoaderSettings = ' . wp_json_encode( $settings ) . ';';
$data = $wp_scripts->get_data( 'customize-loader', 'data' ); $data = $wp_scripts->get_data( 'customize-loader', 'data' );
if ( $data ) if ( $data )

View File

@ -94,7 +94,7 @@ function wp_version_check( $extra_stats = array(), $force_check = false ) {
); );
$post_body = array( $post_body = array(
'translations' => json_encode( $translations ), 'translations' => wp_json_encode( $translations ),
); );
if ( is_array( $extra_stats ) ) if ( is_array( $extra_stats ) )
@ -274,16 +274,16 @@ function wp_update_plugins( $extra_stats = array() ) {
$options = array( $options = array(
'timeout' => $timeout, 'timeout' => $timeout,
'body' => array( 'body' => array(
'plugins' => json_encode( $to_send ), 'plugins' => wp_json_encode( $to_send ),
'translations' => json_encode( $translations ), 'translations' => wp_json_encode( $translations ),
'locale' => json_encode( $locales ), 'locale' => wp_json_encode( $locales ),
'all' => json_encode( true ), 'all' => wp_json_encode( true ),
), ),
'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' ) 'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' )
); );
if ( $extra_stats ) { if ( $extra_stats ) {
$options['body']['update_stats'] = json_encode( $extra_stats ); $options['body']['update_stats'] = wp_json_encode( $extra_stats );
} }
$url = $http_url = 'http://api.wordpress.org/plugins/update-check/1.1/'; $url = $http_url = 'http://api.wordpress.org/plugins/update-check/1.1/';
@ -437,15 +437,15 @@ function wp_update_themes( $extra_stats = array() ) {
$options = array( $options = array(
'timeout' => $timeout, 'timeout' => $timeout,
'body' => array( 'body' => array(
'themes' => json_encode( $request ), 'themes' => wp_json_encode( $request ),
'translations' => json_encode( $translations ), 'translations' => wp_json_encode( $translations ),
'locale' => json_encode( $locales ), 'locale' => wp_json_encode( $locales ),
), ),
'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' ) 'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' )
); );
if ( $extra_stats ) { if ( $extra_stats ) {
$options['body']['update_stats'] = json_encode( $extra_stats ); $options['body']['update_stats'] = wp_json_encode( $extra_stats );
} }
$url = $http_url = 'http://api.wordpress.org/themes/update-check/1.1/'; $url = $http_url = 'http://api.wordpress.org/themes/update-check/1.1/';

View File

@ -4,7 +4,7 @@
* *
* @global string $wp_version * @global string $wp_version
*/ */
$wp_version = '4.1-alpha-30054'; $wp_version = '4.1-alpha-30055';
/** /**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.