Prevent users from entering strings that will be interpreted as serialized arrays/objects on the way out. fixes #2591
git-svn-id: http://svn.automattic.com/wordpress/trunk@4382 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
b77b63ebd7
commit
854cf56a7d
|
@ -981,6 +981,18 @@ function list_meta($meta) {
|
||||||
$style = '';
|
$style = '';
|
||||||
if ('_' == $entry['meta_key'] { 0 })
|
if ('_' == $entry['meta_key'] { 0 })
|
||||||
$style .= ' hidden';
|
$style .= ' hidden';
|
||||||
|
|
||||||
|
if ( is_serialized($entry['meta_value']) ) {
|
||||||
|
if ( 's' == $entry['meta_value']{0} ) {
|
||||||
|
// this is a serialized string, so we should display it
|
||||||
|
$entry['meta_value'] = maybe_unserialize($entry['meta_value']);
|
||||||
|
} else {
|
||||||
|
// this is a serialized array/object so we should NOT display it
|
||||||
|
--$count;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$key_js = js_escape($entry['meta_key']);
|
$key_js = js_escape($entry['meta_key']);
|
||||||
$entry['meta_key'] = wp_specialchars( $entry['meta_key'], true );
|
$entry['meta_key'] = wp_specialchars( $entry['meta_key'], true );
|
||||||
$entry['meta_value'] = wp_specialchars( $entry['meta_value'], true );
|
$entry['meta_value'] = wp_specialchars( $entry['meta_value'], true );
|
||||||
|
@ -1056,7 +1068,8 @@ function add_meta($post_ID) {
|
||||||
|
|
||||||
$metakeyselect = $wpdb->escape(stripslashes(trim($_POST['metakeyselect'])));
|
$metakeyselect = $wpdb->escape(stripslashes(trim($_POST['metakeyselect'])));
|
||||||
$metakeyinput = $wpdb->escape(stripslashes(trim($_POST['metakeyinput'])));
|
$metakeyinput = $wpdb->escape(stripslashes(trim($_POST['metakeyinput'])));
|
||||||
$metavalue = $wpdb->escape(stripslashes(trim($_POST['metavalue'])));
|
$metavalue = prepare_data(stripslashes((trim($_POST['metavalue']))));
|
||||||
|
$metavalue = $wpdb->escape($metavalue);
|
||||||
|
|
||||||
if ( ('0' === $metavalue || !empty ($metavalue)) && ((('#NONE#' != $metakeyselect) && !empty ($metakeyselect)) || !empty ($metakeyinput)) ) {
|
if ( ('0' === $metavalue || !empty ($metavalue)) && ((('#NONE#' != $metakeyselect) && !empty ($metakeyselect)) || !empty ($metakeyinput)) ) {
|
||||||
// We have a key/value pair. If both the select and the
|
// We have a key/value pair. If both the select and the
|
||||||
|
@ -1087,8 +1100,9 @@ function delete_meta($mid) {
|
||||||
|
|
||||||
function update_meta($mid, $mkey, $mvalue) {
|
function update_meta($mid, $mkey, $mvalue) {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
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
|
||||||
|
$mvalue = serialize($mvalue);
|
||||||
$mid = (int) $mid;
|
$mid = (int) $mid;
|
||||||
|
|
||||||
return $wpdb->query("UPDATE $wpdb->postmeta SET meta_key = '$mkey', meta_value = '$mvalue' WHERE meta_id = '$mid'");
|
return $wpdb->query("UPDATE $wpdb->postmeta SET meta_key = '$mkey', meta_value = '$mvalue' WHERE meta_id = '$mid'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,23 +124,32 @@ default:
|
||||||
<table width="98%">
|
<table width="98%">
|
||||||
<?php
|
<?php
|
||||||
$options = $wpdb->get_results("SELECT * FROM $wpdb->options ORDER BY option_name");
|
$options = $wpdb->get_results("SELECT * FROM $wpdb->options ORDER BY option_name");
|
||||||
foreach ( (array) $options as $option )
|
|
||||||
$options_to_update[] = $option->option_name;
|
|
||||||
$options_to_update = implode(',', $options_to_update);
|
|
||||||
?>
|
|
||||||
|
|
||||||
<input type="hidden" name="page_options" value="<?php echo $options_to_update; ?>" />
|
|
||||||
|
|
||||||
<?php
|
|
||||||
foreach ( (array) $options as $option) :
|
foreach ( (array) $options as $option) :
|
||||||
|
$disabled = '';
|
||||||
|
if ( is_serialized($option->option_value) ) {
|
||||||
|
if ( 's' == $option->option_value{0} ) {
|
||||||
|
// this is a serialized string, so we should display it
|
||||||
|
$value = wp_specialchars(maybe_unserialize($option->option_value), 'single');
|
||||||
|
$options_to_update[] = $option->option_name;
|
||||||
|
$class = 'all-options';
|
||||||
|
} else {
|
||||||
|
$value = 'SERIALIZED DATA';
|
||||||
|
$disabled = ' disabled="disabled"';
|
||||||
|
$class = 'all-options disabled';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
$value = wp_specialchars($option->option_value, 'single');
|
$value = wp_specialchars($option->option_value, 'single');
|
||||||
|
$options_to_update[] = $option->option_name;
|
||||||
|
$class = 'all-options';
|
||||||
|
}
|
||||||
echo "
|
echo "
|
||||||
<tr>
|
<tr>
|
||||||
<th scope='row'><label for='$option->option_name'>$option->option_name</label></th>
|
<th scope='row'><label for='$option->option_name'>$option->option_name</label></th>
|
||||||
<td>";
|
<td>";
|
||||||
|
|
||||||
if (stristr($value, "\n")) echo "<textarea class='all-options' name='$option->option_name' id='$option->option_name' cols='30' rows='5'>$value</textarea>";
|
if (stristr($value, "\n")) echo "<textarea class='$class' name='$option->option_name' id='$option->option_name' cols='30' rows='5'>$value</textarea>";
|
||||||
else echo "<input class='all-options' type='text' name='$option->option_name' id='$option->option_name' size='30' value='" . $value . "' />";
|
else echo "<input class='$class' type='text' name='$option->option_name' id='$option->option_name' size='30' value='" . $value . "'$disabled />";
|
||||||
|
|
||||||
echo "</td>
|
echo "</td>
|
||||||
<td>$option->option_description</td>
|
<td>$option->option_description</td>
|
||||||
|
@ -148,7 +157,8 @@ foreach ( (array) $options as $option) :
|
||||||
endforeach;
|
endforeach;
|
||||||
?>
|
?>
|
||||||
</table>
|
</table>
|
||||||
<p class="submit"><input type="submit" name="Update" value="<?php _e('Update Options »') ?>" /></p>
|
<?php $options_to_update = implode(',', $options_to_update); ?>
|
||||||
|
<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 »') ?>" /></p>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -445,6 +445,10 @@ textarea.all-options, input.all-options {
|
||||||
width: 250px;
|
width: 250px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input.disabled, textarea.disabled {
|
||||||
|
background: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
#adminmenu {
|
#adminmenu {
|
||||||
background: #83B4D8;
|
background: #83B4D8;
|
||||||
border-top: 3px solid #448abd;
|
border-top: 3px solid #448abd;
|
||||||
|
|
|
@ -156,12 +156,30 @@ function get_lastpostmodified($timezone = 'server') {
|
||||||
}
|
}
|
||||||
|
|
||||||
function maybe_unserialize($original) {
|
function maybe_unserialize($original) {
|
||||||
|
if ( is_serialized($original) ) // don't attempt to unserialize data that wasn't serialized going in
|
||||||
if ( false !== $gm = @ unserialize($original) )
|
if ( false !== $gm = @ unserialize($original) )
|
||||||
return $gm;
|
return $gm;
|
||||||
else
|
|
||||||
return $original;
|
return $original;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function is_serialized($data) {
|
||||||
|
if ( !is_string($data) ) // if it isn't a string, it isn't serialized
|
||||||
|
return false;
|
||||||
|
$data = trim($data);
|
||||||
|
if ( preg_match("/^[adobis]:[0-9]+:.*[;}]/si",$data) ) // this should fetch all legitimately serialized data
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function is_serialized_string($data) {
|
||||||
|
if ( !is_string($data) ) // if it isn't a string, it isn't a serialized string
|
||||||
|
return false;
|
||||||
|
$data = trim($data);
|
||||||
|
if ( preg_match("/^s:[0-9]+:.*[;}]/si",$data) ) // this should fetch all serialized strings
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Options functions */
|
/* Options functions */
|
||||||
|
|
||||||
function get_option($setting) {
|
function get_option($setting) {
|
||||||
|
@ -239,8 +257,7 @@ function update_option($option_name, $newvalue) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$_newvalue = $newvalue;
|
$_newvalue = $newvalue;
|
||||||
if ( is_array($newvalue) || is_object($newvalue) )
|
$newvalue = prepare_data($newvalue);
|
||||||
$newvalue = serialize($newvalue);
|
|
||||||
|
|
||||||
wp_cache_set($option_name, $newvalue, 'options');
|
wp_cache_set($option_name, $newvalue, 'options');
|
||||||
|
|
||||||
|
@ -262,8 +279,7 @@ function add_option($name, $value = '', $description = '', $autoload = 'yes') {
|
||||||
if ( false !== get_option($name) )
|
if ( false !== get_option($name) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( is_array($value) || is_object($value) )
|
$value = prepare_data($value);
|
||||||
$value = serialize($value);
|
|
||||||
|
|
||||||
wp_cache_set($name, $value, 'options');
|
wp_cache_set($name, $value, 'options');
|
||||||
|
|
||||||
|
@ -285,6 +301,16 @@ function delete_option($name) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function prepare_data($data) {
|
||||||
|
if ( is_string($data) )
|
||||||
|
$data = trim($data);
|
||||||
|
elseif ( is_array($data) || is_object($data) )
|
||||||
|
return serialize($data);
|
||||||
|
if ( is_serialized($data) )
|
||||||
|
return serialize($data);
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
function gzip_compression() {
|
function gzip_compression() {
|
||||||
if ( !get_option('gzipcompression') ) return false;
|
if ( !get_option('gzipcompression') ) return false;
|
||||||
|
|
||||||
|
|
|
@ -78,9 +78,7 @@ function get_userdata( $user_id ) {
|
||||||
|
|
||||||
if ($metavalues) {
|
if ($metavalues) {
|
||||||
foreach ( $metavalues as $meta ) {
|
foreach ( $metavalues as $meta ) {
|
||||||
@ $value = unserialize($meta->meta_value);
|
$value = maybe_unserialize($meta->meta_value);
|
||||||
if ($value === FALSE)
|
|
||||||
$value = $meta->meta_value;
|
|
||||||
$user->{$meta->meta_key} = $value;
|
$user->{$meta->meta_key} = $value;
|
||||||
|
|
||||||
// We need to set user_level from meta, not row
|
// We need to set user_level from meta, not row
|
||||||
|
@ -131,9 +129,7 @@ function get_userdatabylogin($user_login) {
|
||||||
|
|
||||||
if ($metavalues) {
|
if ($metavalues) {
|
||||||
foreach ( $metavalues as $meta ) {
|
foreach ( $metavalues as $meta ) {
|
||||||
@ $value = unserialize($meta->meta_value);
|
$value = maybe_unserialize($meta->meta_value);
|
||||||
if ($value === FALSE)
|
|
||||||
$value = $meta->meta_value;
|
|
||||||
$user->{$meta->meta_key} = $value;
|
$user->{$meta->meta_key} = $value;
|
||||||
|
|
||||||
// We need to set user_level from meta, not row
|
// We need to set user_level from meta, not row
|
||||||
|
|
|
@ -229,14 +229,13 @@ function add_post_meta($post_id, $key, $value, $unique = false) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$original = $value;
|
$post_meta_cache[$post_id][$key][] = $value;
|
||||||
if ( is_array($value) || is_object($value) )
|
|
||||||
$value = $wpdb->escape(serialize($value));
|
$value = prepare_data($value);
|
||||||
|
$value = $wpdb->escape($value);
|
||||||
|
|
||||||
$wpdb->query("INSERT INTO $wpdb->postmeta (post_id,meta_key,meta_value) VALUES ('$post_id','$key','$value')");
|
$wpdb->query("INSERT INTO $wpdb->postmeta (post_id,meta_key,meta_value) VALUES ('$post_id','$key','$value')");
|
||||||
|
|
||||||
$post_meta_cache[$post_id][$key][] = $original;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,12 +310,12 @@ function update_post_meta($post_id, $key, $value, $prev_value = '') {
|
||||||
$post_id = (int) $post_id;
|
$post_id = (int) $post_id;
|
||||||
|
|
||||||
$original_value = $value;
|
$original_value = $value;
|
||||||
if ( is_array($value) || is_object($value) )
|
$value = prepare_data($value);
|
||||||
$value = $wpdb->escape(serialize($value));
|
$value = $wpdb->escape($value);
|
||||||
|
|
||||||
$original_prev = $prev_value;
|
$original_prev = $prev_value;
|
||||||
if ( is_array($prev_value) || is_object($prev_value) )
|
$prev_value = prepare_data($prev_value);
|
||||||
$prev_value = $wpdb->escape(serialize($prev_value));
|
$prev_value = $wpdb->escape($prev_value);
|
||||||
|
|
||||||
if (! $wpdb->get_var("SELECT meta_key FROM $wpdb->postmeta WHERE meta_key = '$key' AND post_id = '$post_id'") ) {
|
if (! $wpdb->get_var("SELECT meta_key FROM $wpdb->postmeta WHERE meta_key = '$key' AND post_id = '$post_id'") ) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -114,9 +114,10 @@ function update_usermeta( $user_id, $meta_key, $meta_value ) {
|
||||||
return false;
|
return false;
|
||||||
$meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key);
|
$meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key);
|
||||||
|
|
||||||
if ( is_array($meta_value) || is_object($meta_value) )
|
// FIXME: usermeta data is assumed to be already escaped
|
||||||
$meta_value = serialize($meta_value);
|
$meta_value = stripslashes($meta_value);
|
||||||
$meta_value = trim( $meta_value );
|
$meta_value = prepare_data($meta_value);
|
||||||
|
$meta_value = $wpdb->escape($meta_value);
|
||||||
|
|
||||||
if (empty($meta_value)) {
|
if (empty($meta_value)) {
|
||||||
return delete_usermeta($user_id, $meta_key);
|
return delete_usermeta($user_id, $meta_key);
|
||||||
|
|
Loading…
Reference in New Issue