Make WordPress Core

Ticket #2591: serialize-TAKE_4.diff

File serialize-TAKE_4.diff, 8.7 KB (added by markjaquith, 18 years ago)

Take 4

  • wp-includes/post.php

     
    229229                }
    230230        }
    231231
    232         $original = $value;
    233         if ( is_array($value) || is_object($value) )
    234                 $value = $wpdb->escape(serialize($value));
     232        $post_meta_cache[$post_id][$key][] = $value;
    235233
     234        $value = prepare_data($value);
     235        $value = $wpdb->escape($value);
     236
    236237        $wpdb->query("INSERT INTO $wpdb->postmeta (post_id,meta_key,meta_value) VALUES ('$post_id','$key','$value')");
    237238
    238         $post_meta_cache[$post_id][$key][] = $original;
    239 
    240239        return true;
    241240}
    242241
     
    311310        $post_id = (int) $post_id;
    312311
    313312        $original_value = $value;
    314         if ( is_array($value) || is_object($value) )
    315                 $value = $wpdb->escape(serialize($value));
     313        $value = prepare_data($value);
     314        $value = $wpdb->escape($value);
    316315
    317316        $original_prev = $prev_value;
    318         if ( is_array($prev_value) || is_object($prev_value) )
    319                 $prev_value = $wpdb->escape(serialize($prev_value));
     317        $prev_value = prepare_data($prev_value);
     318        $prev_value = $wpdb->escape($prev_value);
    320319
    321320        if (! $wpdb->get_var("SELECT meta_key FROM $wpdb->postmeta WHERE meta_key = '$key' AND post_id = '$post_id'") ) {
    322321                return false;
  • wp-includes/pluggable.php

     
    7878
    7979        if ($metavalues) {
    8080                foreach ( $metavalues as $meta ) {
    81                         @ $value = unserialize($meta->meta_value);
    82                         if ($value === FALSE)
    83                                 $value = $meta->meta_value;
     81                        $value = maybe_unserialize($meta->meta_value);
    8482                        $user->{$meta->meta_key} = $value;
    8583
    8684                        // We need to set user_level from meta, not row
     
    131129
    132130        if ($metavalues) {
    133131                foreach ( $metavalues as $meta ) {
    134                         @ $value = unserialize($meta->meta_value);
    135                         if ($value === FALSE)
    136                                 $value = $meta->meta_value;
     132                        $value = maybe_unserialize($meta->meta_value);
    137133                        $user->{$meta->meta_key} = $value;
    138134
    139135                        // We need to set user_level from meta, not row
  • wp-includes/functions.php

     
    156156}
    157157
    158158function maybe_unserialize($original) {
    159         if ( false !== $gm = @ unserialize($original) )
    160                 return $gm;
    161         else
    162                 return $original;
     159        if ( is_serialized($original) ) // don't attempt to unserialize data that wasn't serialized going in
     160                if ( false !== $gm = @ unserialize($original) )
     161                        return $gm;
     162        return $original;
    163163}
    164164
     165function is_serialized($data) {
     166        if ( !is_string($data) ) // if it isn't a string, it isn't serialized
     167                return false;
     168        $data = trim($data);
     169        if ( preg_match("/^[adobis]:[0-9]+:.*[;}]/si",$data) ) // this should fetch all legitimately serialized data
     170                return true;
     171        return false;
     172}
     173
     174function is_serialized_string($data) {
     175        if ( !is_string($data) ) // if it isn't a string, it isn't a serialized string
     176                return false;
     177        $data = trim($data);
     178        if ( preg_match("/^s:[0-9]+:.*[;}]/si",$data) ) // this should fetch all serialized strings
     179                return true;
     180        return false;
     181}
     182
    165183/* Options functions */
    166184
    167185function get_option($setting) {
     
    239257        }
    240258
    241259        $_newvalue = $newvalue;
    242         if ( is_array($newvalue) || is_object($newvalue) )
    243                 $newvalue = serialize($newvalue);
     260        $newvalue = prepare_data($newvalue);
    244261
    245262        wp_cache_set($option_name, $newvalue, 'options');
    246263
     
    262279        if ( false !== get_option($name) )
    263280                return;
    264281
    265         if ( is_array($value) || is_object($value) )
    266                 $value = serialize($value);
     282        $value = prepare_data($value);
    267283
    268284        wp_cache_set($name, $value, 'options');
    269285
     
    285301        return true;
    286302}
    287303
     304function prepare_data($data) {
     305        if ( is_string($data) )
     306                $data = trim($data);
     307        elseif ( is_array($data) || is_object($data) )
     308                return serialize($data);
     309        if ( is_serialized($data) )
     310                return serialize($data);
     311        return $data;
     312}
     313
    288314function gzip_compression() {
    289315        if ( !get_option('gzipcompression') ) return false;
    290316
  • wp-includes/user.php

     
    114114                return false;
    115115        $meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key);
    116116
    117         if ( is_array($meta_value) || is_object($meta_value) )
    118                 $meta_value = serialize($meta_value);
    119         $meta_value = trim( $meta_value );
     117        // FIXME: usermeta data is assumed to be already escaped
     118        $meta_value = stripslashes($meta_value);
     119        $meta_value = prepare_data($meta_value);
     120        $meta_value = $wpdb->escape($meta_value);
    120121
    121122        if (empty($meta_value)) {
    122123                return delete_usermeta($user_id, $meta_key);
  • wp-admin/admin-functions.php

     
    981981                        $style = '';
    982982                if ('_' == $entry['meta_key'] { 0 })
    983983                        $style .= ' hidden';
     984
     985                if ( is_serialized($entry['meta_value']) ) {
     986                        if ( 's' == $entry['meta_value']{0} ) {
     987                                // this is a serialized string, so we should display it
     988                                $entry['meta_value'] = maybe_unserialize($entry['meta_value']);
     989                        } else {
     990                                // this is a serialized array/object so we should NOT display it
     991                                --$count;
     992                                continue;
     993                        }
     994                }
     995
    984996                $key_js = js_escape($entry['meta_key']);
    985997                $entry['meta_key'] = wp_specialchars( $entry['meta_key'], true );
    986998                $entry['meta_value'] = wp_specialchars( $entry['meta_value'], true );
     
    10561068
    10571069        $metakeyselect = $wpdb->escape(stripslashes(trim($_POST['metakeyselect'])));
    10581070        $metakeyinput = $wpdb->escape(stripslashes(trim($_POST['metakeyinput'])));
    1059         $metavalue = $wpdb->escape(stripslashes(trim($_POST['metavalue'])));
     1071        $metavalue = prepare_data(stripslashes((trim($_POST['metavalue']))));
     1072        $metavalue = $wpdb->escape($metavalue);
    10601073
    10611074        if ( ('0' === $metavalue || !empty ($metavalue)) && ((('#NONE#' != $metakeyselect) && !empty ($metakeyselect)) || !empty ($metakeyinput)) ) {
    10621075                // We have a key/value pair. If both the select and the
     
    10871100
    10881101function update_meta($mid, $mkey, $mvalue) {
    10891102        global $wpdb;
     1103        if ( is_serialized(stripslashes($mvalue)) ) // $mvalue looks to be already serialized, so we should serialize it again to prevent the data from coming out in a different form than it came in
     1104                $mvalue = serialize($mvalue);
    10901105        $mid = (int) $mid;
    1091 
    10921106        return $wpdb->query("UPDATE $wpdb->postmeta SET meta_key = '$mkey', meta_value = '$mvalue' WHERE meta_id = '$mid'");
    10931107}
    10941108
  • wp-admin/options.php

     
    124124  <table width="98%">
    125125<?php
    126126$options = $wpdb->get_results("SELECT * FROM $wpdb->options ORDER BY option_name");
    127 foreach ( (array) $options as $option )
    128         $options_to_update[] = $option->option_name;
    129 $options_to_update = implode(',', $options_to_update);
    130 ?>
    131127
    132 <input type="hidden" name="page_options" value="<?php echo $options_to_update; ?>" />
    133 
    134 <?php
    135128foreach ( (array) $options as $option) :
    136         $value = wp_specialchars($option->option_value, 'single');
     129        $disabled = '';
     130        if ( is_serialized($option->option_value) ) {
     131                if ( 's' == $option->option_value{0} ) {
     132                        // this is a serialized string, so we should display it
     133                        $value = wp_specialchars(maybe_unserialize($option->option_value), 'single');
     134                        $options_to_update[] = $option->option_name;
     135                } else {
     136                        $value = '%SERIALIZED_DATA%';
     137                        $disabled = ' disabled="disabled"';
     138                }
     139        } else {
     140                $value = wp_specialchars($option->option_value, 'single');
     141                $options_to_update[] = $option->option_name;
     142        }
    137143        echo "
    138144<tr>
    139145        <th scope='row'><label for='$option->option_name'>$option->option_name</label></th>
    140146<td>";
    141147
    142148        if (stristr($value, "\n")) echo "<textarea class='all-options' name='$option->option_name' id='$option->option_name' cols='30' rows='5'>$value</textarea>";
    143         else echo "<input class='all-options' type='text' name='$option->option_name' id='$option->option_name' size='30' value='" . $value . "' />";
     149        else echo "<input class='all-options' type='text' name='$option->option_name' id='$option->option_name' size='30' value='" . $value . "'$disabled />";
    144150       
    145151        echo "</td>
    146152        <td>$option->option_description</td>
     
    148154endforeach;
    149155?>
    150156  </table>
    151 <p class="submit"><input type="submit" name="Update" value="<?php _e('Update Options &raquo;') ?>" /></p>
     157<?php $options_to_update = implode(',', $options_to_update); ?>
     158<p class="submit"><input type="hidden" name="page_options" value="<?php echo wp_specialchars($options_to_update, true); ?>" /><input type="submit" name="Update" value="<?php _e('Update Options &raquo;') ?>" /></p>
    152159  </form>
    153160</div>
    154161