WordPress.org

Make WordPress Core

Changeset 30055


Ignore:
Timestamp:
10/28/14 18:34:16 (38 hours ago)
Author:
pento
Message:

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.

Location:
trunk
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/customize.php

    r30014 r30055  
    275275    ?> 
    276276    <script type="text/javascript"> 
    277         var _wpCustomizeSettings = <?php echo json_encode( $settings ); ?>; 
     277        var _wpCustomizeSettings = <?php echo wp_json_encode( $settings ); ?>; 
    278278    </script> 
    279279</div> 
  • trunk/src/wp-admin/includes/ajax-actions.php

    r29758 r30055  
    287287    } 
    288288 
    289     wp_die( json_encode( $return ) ); 
     289    wp_die( wp_json_encode( $return ) ); 
    290290} 
    291291 
     
    13661366        $markup = ob_get_clean(); 
    13671367 
    1368         echo json_encode(array( 
     1368        echo wp_json_encode(array( 
    13691369            'replace-id' => $type . '-' . $item->name, 
    13701370            'markup' => $markup, 
     
    13951395        wp_die( 0 ); 
    13961396 
    1397     echo json_encode( $results ); 
     1397    echo wp_json_encode( $results ); 
    13981398    echo "\n"; 
    13991399 
     
    18411841        $wp_filetype = wp_check_filetype_and_ext( $_FILES['async-upload']['tmp_name'], $_FILES['async-upload']['name'], false ); 
    18421842        if ( ! wp_match_mime_types( 'image', $wp_filetype['type'] ) ) { 
    1843             echo json_encode( array( 
     1843            echo wp_json_encode( array( 
    18441844                'success' => false, 
    18451845                'data'    => array( 
     
    18561856 
    18571857    if ( is_wp_error( $attachment_id ) ) { 
    1858         echo json_encode( array( 
     1858        echo wp_json_encode( array( 
    18591859            'success' => false, 
    18601860            'data'    => array( 
     
    18781878        wp_die(); 
    18791879 
    1880     echo json_encode( array( 
     1880    echo wp_json_encode( array( 
    18811881        'success' => true, 
    18821882        'data'    => $attachment, 
     
    19031903        case 'save' : 
    19041904            $msg = wp_save_image($attachment_id); 
    1905             $msg = json_encode($msg); 
     1905            $msg = wp_json_encode($msg); 
    19061906            wp_die( $msg ); 
    19071907            break; 
  • trunk/src/wp-admin/includes/class-wp-list-table.php

    r29707 r30055  
    10591059        } 
    10601060 
    1061         die( json_encode( $response ) ); 
     1061        die( wp_json_encode( $response ) ); 
    10621062    } 
    10631063 
     
    10761076        ); 
    10771077 
    1078         printf( "<script type='text/javascript'>list_args = %s;</script>\n", json_encode( $args ) ); 
     1078        printf( "<script type='text/javascript'>list_args = %s;</script>\n", wp_json_encode( $args ) ); 
    10791079    } 
    10801080} 
  • trunk/src/wp-admin/includes/class-wp-themes-list-table.php

    r29767 r30055  
    274274            $args = array_merge( $args, $extra_args ); 
    275275 
    276         printf( "<script type='text/javascript'>var theme_list_args = %s;</script>\n", json_encode( $args ) ); 
     276        printf( "<script type='text/javascript'>var theme_list_args = %s;</script>\n", wp_json_encode( $args ) ); 
    277277        parent::_js_vars(); 
    278278    } 
  • trunk/src/wp-admin/includes/media.php

    r29776 r30055  
    18271827?> 
    18281828var resize_height = <?php echo $large_size_h; ?>, resize_width = <?php echo $large_size_w; ?>, 
    1829 wpUploaderInit = <?php echo json_encode($plupload_init); ?>; 
     1829wpUploaderInit = <?php echo wp_json_encode( $plupload_init ); ?>; 
    18301830</script> 
    18311831 
  • trunk/src/wp-admin/includes/misc.php

    r29707 r30055  
    622622                <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 ); ?> /> 
    623623                <input type="hidden" class="css_url" value="<?php echo esc_url( $color_info->url ); ?>" /> 
    624                 <input type="hidden" class="icon_colors" value="<?php echo esc_attr( json_encode( array( 'icons' => $color_info->icon_colors ) ) ); ?>" /> 
     624                <input type="hidden" class="icon_colors" value="<?php echo esc_attr( wp_json_encode( array( 'icons' => $color_info->icon_colors ) ) ); ?>" /> 
    625625                <label for="admin_color_<?php echo esc_attr( $color ); ?>"><?php echo esc_html( $color_info->name ); ?></label> 
    626626                <table class="color-palette"> 
     
    666666    } 
    667667 
    668     echo '<script type="text/javascript">var _wpColorScheme = ' . json_encode( array( 'icons' => $icon_colors ) ) . ";</script>\n"; 
     668    echo '<script type="text/javascript">var _wpColorScheme = ' . wp_json_encode( array( 'icons' => $icon_colors ) ) . ";</script>\n"; 
    669669} 
    670670add_action( 'admin_head', 'wp_color_scheme_settings' ); 
  • trunk/src/wp-admin/includes/nav-menu.php

    r29206 r30055  
    357357                    echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', array( get_post( $object_id ) ) ), 0, (object) $args ); 
    358358                } elseif ( 'json' == $response_format ) { 
    359                     echo json_encode( 
     359                    echo wp_json_encode( 
    360360                        array( 
    361361                            'ID' => $object_id, 
     
    374374                } elseif ( 'json' == $response_format ) { 
    375375                    $post_obj = get_term( $object_id, $object_type ); 
    376                     echo json_encode( 
     376                    echo wp_json_encode( 
    377377                        array( 
    378378                            'ID' => $object_id, 
     
    402402                    echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', array( get_post( $var_by_ref ) ) ), 0, (object) $args ); 
    403403                } elseif ( 'json' == $response_format ) { 
    404                     echo json_encode( 
     404                    echo wp_json_encode( 
    405405                        array( 
    406406                            'ID' => get_the_ID(), 
     
    423423                    echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', array( $term ) ), 0, (object) $args ); 
    424424                } elseif ( 'json' == $response_format ) { 
    425                     echo json_encode( 
     425                    echo wp_json_encode( 
    426426                        array( 
    427427                            'ID' => $term->term_id, 
  • trunk/src/wp-admin/includes/template.php

    r30040 r30055  
    19531953        //<![CDATA[ 
    19541954        (function($){ 
    1955             var options = <?php echo json_encode( $args ); ?>, setup; 
     1955            var options = <?php echo wp_json_encode( $args ); ?>, setup; 
    19561956 
    19571957            if ( ! options ) 
  • trunk/src/wp-includes/class-wp-customize-manager.php

    r30014 r30055  
    518518        ?> 
    519519        <script type="text/javascript"> 
    520             var _wpCustomizeSettings = <?php echo json_encode( $settings ); ?>; 
     520            var _wpCustomizeSettings = <?php echo wp_json_encode( $settings ); ?>; 
    521521        </script> 
    522522        <?php 
  • trunk/src/wp-includes/class-wp-customize-widgets.php

    r29903 r30055  
    741741            'customize-widgets', 
    742742            'data', 
    743             sprintf( 'var _wpCustomizeWidgetsSettings = %s;', json_encode( $settings ) ) 
     743            sprintf( 'var _wpCustomizeWidgetsSettings = %s;', wp_json_encode( $settings ) ) 
    744744        ); 
    745745    } 
     
    10561056        ?> 
    10571057        <script type="text/javascript"> 
    1058             var _wpWidgetCustomizerPreviewSettings = <?php echo json_encode( $settings ); ?>; 
     1058            var _wpWidgetCustomizerPreviewSettings = <?php echo wp_json_encode( $settings ); ?>; 
    10591059        </script> 
    10601060        <?php 
  • trunk/src/wp-includes/class-wp-editor.php

    r30002 r30055  
    501501 
    502502                if ( ! empty( $mce_external_plugins ) ) { 
    503                     self::$first_init['external_plugins'] = json_encode( $mce_external_plugins ); 
     503                    self::$first_init['external_plugins'] = wp_json_encode( $mce_external_plugins ); 
    504504                } 
    505505 
     
    987987        } 
    988988 
    989         return "tinymce.addI18n( '$mce_locale', " . json_encode( $mce_translation ) . ");\n" . 
     989        return "tinymce.addI18n( '$mce_locale', " . wp_json_encode( $mce_translation ) . ");\n" . 
    990990            "tinymce.ScriptLoader.markDone( '$baseurl/langs/$mce_locale.js' );\n"; 
    991991    } 
  • trunk/src/wp-includes/class.wp-scripts.php

    r28907 r30055  
    168168        } 
    169169 
    170         $script = "var $object_name = " . json_encode($l10n) . ';'; 
     170        $script = "var $object_name = " . wp_json_encode( $l10n ) . ';'; 
    171171 
    172172        if ( !empty($after) ) 
  • trunk/src/wp-includes/functions.php

    r29915 r30055  
    26142614 
    26152615/** 
     2616 * Encode a variable into JSON, with some sanity checks 
     2617 * 
     2618 * @since 4.1.0 
     2619 * 
     2620 * @param mixed $data    Variable (usually an array or object) to encode as JSON 
     2621 * @param int   $options Options to be passed to json_encode(). Default 0. 
     2622 * @param int   $depth   Maximum depth to walk through $data. Must be greater than 0, default 512.t 
     2623 * 
     2624 * @return bool|string The JSON encoded string, or false if it cannot be encoded 
     2625 */ 
     2626function wp_json_encode( $data, $options = 0, $depth = 512 ) { 
     2627    // json_encode has had extra params added over the years. 
     2628    // $options was added in 5.3, and $depth in 5.5. 
     2629    // We need to make sure we call it with the correct arguments. 
     2630    if ( version_compare( PHP_VERSION, '5.5', '>=' ) ) { 
     2631        $args = array( $data, $options, $depth ); 
     2632    } else if ( version_compare( PHP_VERSION, '5.3', '>=' ) ) { 
     2633        $args = array( $data, $options ); 
     2634    } else { 
     2635        $args = array( $data ); 
     2636    } 
     2637 
     2638    $json = call_user_func_array( 'json_encode', $args ); 
     2639 
     2640    if ( false !== $json ) { 
     2641        // If json_encode was successful, no need to do more sanity checking 
     2642        return $json; 
     2643    } 
     2644 
     2645    try { 
     2646        $args[0] = _wp_json_sanity_check( $data, $depth ); 
     2647    } catch ( Exception $e ) { 
     2648        return false; 
     2649    } 
     2650 
     2651    return call_user_func_array( 'json_encode', $args ); 
     2652} 
     2653 
     2654/** 
     2655 * @ignore 
     2656 */ 
     2657function _wp_json_sanity_check( $data, $depth ) { 
     2658    if ( $depth < 0 ) { 
     2659        throw new Exception( 'Reached depth limit' ); 
     2660    } 
     2661 
     2662    if ( is_array( $data ) ) { 
     2663        $output = array(); 
     2664        foreach ( $data as $id => $el ) { 
     2665            // Don't forget to sanitize the ID! 
     2666            if ( is_string( $id ) ) { 
     2667                $clean_id = _wp_json_convert_string( $id ); 
     2668            } else { 
     2669                $clean_id = $id; 
     2670            } 
     2671 
     2672            // Check the element type, so that we're only recursing if we really have to 
     2673            if ( is_array( $el ) || is_object( $el ) ) { 
     2674                $output[ $clean_id ] = _wp_json_sanity_check( $el, $depth - 1 ); 
     2675            } else if ( is_string( $el ) ) { 
     2676                $output[ $clean_id ] = _wp_json_convert_string( $el ); 
     2677            } else { 
     2678                $output[ $clean_id ] = $el; 
     2679            } 
     2680        } 
     2681    } else if ( is_object( $data ) ) { 
     2682        $output = new stdClass; 
     2683        foreach ( $data as $id => $el ) { 
     2684            if ( is_string( $id ) ) { 
     2685                $clean_id = _wp_json_convert_string( $id ); 
     2686            } else { 
     2687                $clean_id = $id; 
     2688            } 
     2689 
     2690            if ( is_array( $el ) || is_object( $el ) ) { 
     2691                $output->$clean_id = _wp_json_sanity_check( $el, $depth - 1 ); 
     2692            } else if ( is_string( $el ) ) { 
     2693                $output->$clean_id = _wp_json_convert_string( $el ); 
     2694            } else { 
     2695                $output->$clean_id = $el; 
     2696            } 
     2697        } 
     2698    } else if ( is_string( $data ) ) { 
     2699        return _wp_json_convert_string( $data ); 
     2700    } else { 
     2701        return $data; 
     2702    } 
     2703 
     2704    return $output; 
     2705} 
     2706 
     2707/** 
     2708 * @ignore 
     2709 */ 
     2710function _wp_json_convert_string( $string ) { 
     2711    static $use_mb = null; 
     2712    if ( is_null( $use_mb ) ) { 
     2713        $use_mb = function_exists( 'mb_convert_encoding' ); 
     2714    } 
     2715 
     2716    if ( $use_mb ) { 
     2717        $encoding = mb_detect_encoding( $string, mb_detect_order(), true ); 
     2718        if ( $encoding ) { 
     2719            return mb_convert_encoding( $string, 'UTF-8', $encoding ); 
     2720        } else { 
     2721            return mb_convert_encoding( $string, 'UTF-8', 'UTF-8' ); 
     2722        } 
     2723    } else { 
     2724        return wp_check_invalid_utf8( $data, true ); 
     2725    } 
     2726} 
     2727 
     2728/** 
    26162729 * Send a JSON response back to an Ajax request. 
    26172730 * 
     
    26232736function wp_send_json( $response ) { 
    26242737    @header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) ); 
    2625     echo json_encode( $response ); 
     2738    echo wp_json_encode( $response ); 
    26262739    if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) 
    26272740        wp_die(); 
  • trunk/src/wp-includes/media.php

    r29914 r30055  
    13991399    ?></ol> 
    14001400    </noscript> 
    1401     <script type="application/json" class="wp-playlist-script"><?php echo json_encode( $data ) ?></script> 
     1401    <script type="application/json" class="wp-playlist-script"><?php echo wp_json_encode( $data ) ?></script> 
    14021402</div> 
    14031403    <?php 
     
    25832583    ); 
    25842584 
    2585     $script = 'var _wpPluploadSettings = ' . json_encode( $settings ) . ';'; 
     2585    $script = 'var _wpPluploadSettings = ' . wp_json_encode( $settings ) . ';'; 
    25862586 
    25872587    if ( $data ) 
  • trunk/src/wp-includes/theme.php

    r30038 r30055  
    19401940    ); 
    19411941 
    1942     $script = 'var _wpCustomizeLoaderSettings = ' . json_encode( $settings ) . ';'; 
     1942    $script = 'var _wpCustomizeLoaderSettings = ' . wp_json_encode( $settings ) . ';'; 
    19431943 
    19441944    $data = $wp_scripts->get_data( 'customize-loader', 'data' ); 
  • trunk/src/wp-includes/update.php

    r29226 r30055  
    9595 
    9696    $post_body = array( 
    97         'translations' => json_encode( $translations ), 
     97        'translations' => wp_json_encode( $translations ), 
    9898    ); 
    9999 
     
    275275        'timeout' => $timeout, 
    276276        'body' => array( 
    277             'plugins'      => json_encode( $to_send ), 
    278             'translations' => json_encode( $translations ), 
    279             'locale'       => json_encode( $locales ), 
    280             'all'          => json_encode( true ), 
     277            'plugins'      => wp_json_encode( $to_send ), 
     278            'translations' => wp_json_encode( $translations ), 
     279            'locale'       => wp_json_encode( $locales ), 
     280            'all'          => wp_json_encode( true ), 
    281281        ), 
    282282        'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' ) 
     
    284284 
    285285    if ( $extra_stats ) { 
    286         $options['body']['update_stats'] = json_encode( $extra_stats ); 
     286        $options['body']['update_stats'] = wp_json_encode( $extra_stats ); 
    287287    } 
    288288 
     
    438438        'timeout' => $timeout, 
    439439        'body' => array( 
    440             'themes'       => json_encode( $request ), 
    441             'translations' => json_encode( $translations ), 
    442             'locale'       => json_encode( $locales ), 
     440            'themes'       => wp_json_encode( $request ), 
     441            'translations' => wp_json_encode( $translations ), 
     442            'locale'       => wp_json_encode( $locales ), 
    443443        ), 
    444444        'user-agent'    => 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' ) 
     
    446446 
    447447    if ( $extra_stats ) { 
    448         $options['body']['update_stats'] = json_encode( $extra_stats ); 
     448        $options['body']['update_stats'] = wp_json_encode( $extra_stats ); 
    449449    } 
    450450 
  • trunk/tests/phpunit/tests/functions.php

    r29756 r30055  
    530530        $this->assertEquals( array_slice( $original_urls, 0, 8 ), $urls ); 
    531531    } 
     532 
     533    /** 
     534     * @ticket 28786 
     535     */ 
     536    function test_wp_json_encode() { 
     537        $this->assertEquals( wp_json_encode( 'a' ), '"a"' ); 
     538        $this->assertEquals( wp_json_encode( '这' ), '"\u8fd9"' ); 
     539 
     540        $old_charsets = $charsets = mb_detect_order(); 
     541        if ( ! in_array( 'EUC-JP', $charsets ) ) { 
     542            $charsets[] = 'EUC-JP'; 
     543            mb_detect_order( $charsets ); 
     544        } 
     545 
     546        $eucjp = mb_convert_encoding( 'aあb', 'EUC-JP', 'UTF-8' ); 
     547        $utf8 = mb_convert_encoding( $eucjp, 'UTF-8', 'EUC-JP' ); 
     548 
     549        $this->assertEquals( 'aあb', $utf8 ); 
     550 
     551        $this->assertEquals( wp_json_encode( $eucjp ), '"a\u3042b"' ); 
     552 
     553        $this->assertEquals( wp_json_encode( array( 'a' ) ), '["a"]' ); 
     554 
     555        $object = new stdClass; 
     556        $object->a = 'b'; 
     557        $this->assertEquals( wp_json_encode( $object ), '{"a":"b"}' ); 
     558 
     559        mb_detect_order( $old_charsets ); 
     560    } 
     561 
     562    /** 
     563     * @ticket 28786 
     564     */ 
     565    function test_wp_json_encode_depth() { 
     566        $data = array( array( array( 1, 2, 3 ) ) ); 
     567        $json = wp_json_encode( $data, 0, 1 ); 
     568        $this->assertFalse( $json ); 
     569 
     570        $data = array( 'あ', array( array( 1, 2, 3 ) ) ); 
     571        $json = wp_json_encode( $data, 0, 1 ); 
     572        $this->assertFalse( $json ); 
     573    } 
    532574} 
Note: See TracChangeset for help on using the changeset viewer.