<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[BuddyPress][11691] branches/2.9/src: General: ensure values are un/serialized as intended.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="http://buddypress.trac.wordpress.org/changeset/11691">11691</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"http://buddypress.trac.wordpress.org/changeset/11691","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>johnjamesjacoby</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2017-09-09 00:42:06 +0000 (Sat, 09 Sep 2017)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>General: ensure values are un/serialized as intended.

This change provides additional hardening around how some serialized data is manipulated while it's being passed around the application. (Some values were inconsistently or needlessly handled.)

2.9 branch, for 2.9.2.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branches29srcbpactivityclassesclassbpactivityactivityphp">branches/2.9/src/bp-activity/classes/class-bp-activity-activity.php</a></li>
<li><a href="#branches29srcbpactivityclassesclassbpactivitytemplatephp">branches/2.9/src/bp-activity/classes/class-bp-activity-template.php</a></li>
<li><a href="#branches29srcbpxprofilebpxprofilefiltersphp">branches/2.9/src/bp-xprofile/bp-xprofile-filters.php</a></li>
<li><a href="#branches29srcbpxprofilebpxprofilefunctionsphp">branches/2.9/src/bp-xprofile/bp-xprofile-functions.php</a></li>
<li><a href="#branches29srcbpxprofilebpxprofiletemplatephp">branches/2.9/src/bp-xprofile/bp-xprofile-template.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branches29srcbpactivityclassesclassbpactivityactivityphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: branches/2.9/src/bp-activity/classes/class-bp-activity-activity.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- branches/2.9/src/bp-activity/classes/class-bp-activity-activity.php       2017-09-08 10:04:56 UTC (rev 11690)
+++ branches/2.9/src/bp-activity/classes/class-bp-activity-activity.php 2017-09-09 00:42:06 UTC (rev 11691)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1832,7 +1832,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                // Get activities from user meta.
</span><span class="cx" style="display: block; padding: 0 10px">                $favorite_activity_entries = bp_get_user_meta( $user_id, 'bp_favorite_activities', true );
</span><span class="cx" style="display: block; padding: 0 10px">                if ( ! empty( $favorite_activity_entries ) ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        return count( maybe_unserialize( $favorite_activity_entries ) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 return count( $favorite_activity_entries );
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // No favorites.
</span></span></pre></div>
<a id="branches29srcbpactivityclassesclassbpactivitytemplatephp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: branches/2.9/src/bp-activity/classes/class-bp-activity-template.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- branches/2.9/src/bp-activity/classes/class-bp-activity-template.php       2017-09-08 10:04:56 UTC (rev 11690)
+++ branches/2.9/src/bp-activity/classes/class-bp-activity-template.php 2017-09-09 00:42:06 UTC (rev 11691)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -195,7 +195,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $this->disable_blogforum_replies = (bool) bp_core_get_root_option( 'bp-disable-blogforum-comments' );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // Get an array of the logged in user's favorite activities.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $this->my_favs = maybe_unserialize( bp_get_user_meta( bp_loggedin_user_id(), 'bp_favorite_activities', true ) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $this->my_favs = bp_get_user_meta( bp_loggedin_user_id(), 'bp_favorite_activities', true );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // Fetch specific activity items based on ID's.
</span><span class="cx" style="display: block; padding: 0 10px">                if ( !empty( $include ) ) {
</span></span></pre></div>
<a id="branches29srcbpxprofilebpxprofilefiltersphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: branches/2.9/src/bp-xprofile/bp-xprofile-filters.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- branches/2.9/src/bp-xprofile/bp-xprofile-filters.php      2017-09-08 10:04:56 UTC (rev 11690)
+++ branches/2.9/src/bp-xprofile/bp-xprofile-filters.php        2017-09-09 00:42:06 UTC (rev 11691)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -168,11 +168,16 @@
</span><span class="cx" style="display: block; padding: 0 10px">                return $field_value;
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        // Value might be serialized.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // Force reserialization if serialized (avoids mutation, retains integrity)
+       if ( is_serialized( $field_value ) && ( false === $reserialize ) ) {
+               $reserialize = true;
+       }
+
+       // Value might be a serialized array of options.
</ins><span class="cx" style="display: block; padding: 0 10px">         $field_value = maybe_unserialize( $field_value );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        // Filter single value.
-       if ( !is_array( $field_value ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // Sanitize single field value.
+       if ( ! is_array( $field_value ) ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                 $kses_field_value     = xprofile_filter_kses( $field_value, $data_obj );
</span><span class="cx" style="display: block; padding: 0 10px">                $filtered_field_value = wp_rel_nofollow( force_balance_tags( $kses_field_value ) );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -187,16 +192,15 @@
</span><span class="cx" style="display: block; padding: 0 10px">                 */
</span><span class="cx" style="display: block; padding: 0 10px">                $filtered_field_value = apply_filters( 'xprofile_filtered_data_value_before_save', $filtered_field_value, $field_value, $data_obj );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        // Filter each array item independently.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // Sanitize multiple individual option values.
</ins><span class="cx" style="display: block; padding: 0 10px">         } else {
</span><span class="cx" style="display: block; padding: 0 10px">                $filtered_values = array();
</span><span class="cx" style="display: block; padding: 0 10px">                foreach ( (array) $field_value as $value ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $kses_field_value       = xprofile_filter_kses( $value, $data_obj );
-                       $filtered_value         = wp_rel_nofollow( force_balance_tags( $kses_field_value ) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $kses_field_value = xprofile_filter_kses( $value, $data_obj );
+                       $filtered_value   = wp_rel_nofollow( force_balance_tags( $kses_field_value ) );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        /** This filter is documented in bp-xprofile/bp-xprofile-filters.php */
</span><span class="cx" style="display: block; padding: 0 10px">                        $filtered_values[] = apply_filters( 'xprofile_filtered_data_value_before_save', $filtered_value, $value, $data_obj );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
</del><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                if ( !empty( $reserialize ) ) {
</span></span></pre></div>
<a id="branches29srcbpxprofilebpxprofilefunctionsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: branches/2.9/src/bp-xprofile/bp-xprofile-functions.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- branches/2.9/src/bp-xprofile/bp-xprofile-functions.php    2017-09-08 10:04:56 UTC (rev 11690)
+++ branches/2.9/src/bp-xprofile/bp-xprofile-functions.php      2017-09-09 00:42:06 UTC (rev 11691)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -464,6 +464,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">        $field           = new BP_XProfile_ProfileData();
</span><span class="cx" style="display: block; padding: 0 10px">        $field->field_id = $field_id;
</span><span class="cx" style="display: block; padding: 0 10px">        $field->user_id  = $user_id;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+       // Gets un/reserialized via xprofile_sanitize_data_value_before_save()
</ins><span class="cx" style="display: block; padding: 0 10px">         $field->value    = maybe_serialize( $value );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        return $field->save();
</span></span></pre></div>
<a id="branches29srcbpxprofilebpxprofiletemplatephp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: branches/2.9/src/bp-xprofile/bp-xprofile-template.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- branches/2.9/src/bp-xprofile/bp-xprofile-template.php     2017-09-08 10:04:56 UTC (rev 11690)
+++ branches/2.9/src/bp-xprofile/bp-xprofile-template.php       2017-09-09 00:42:06 UTC (rev 11691)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -588,28 +588,23 @@
</span><span class="cx" style="display: block; padding: 0 10px">        function bp_get_the_profile_field_edit_value() {
</span><span class="cx" style="display: block; padding: 0 10px">                global $field;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                /**
-                * Check to see if the posted value is different, if it is re-display this
-                * value as long as it's not empty and a required field.
-                */
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // Make sure field data object exists
</ins><span class="cx" style="display: block; padding: 0 10px">                 if ( ! isset( $field->data ) ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        $field->data = new stdClass;
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                // Default to empty value
</ins><span class="cx" style="display: block; padding: 0 10px">                 if ( ! isset( $field->data->value ) ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        $field->data->value = '';
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                if ( isset( $_POST['field_' . $field->id] ) && $field->data->value != $_POST['field_' . $field->id] ) {
-                       if ( ! empty( $_POST['field_' . $field->id] ) ) {
-                               $field->data->value = $_POST['field_' . $field->id];
-                       } else {
-                               $field->data->value = '';
-                       }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // Was a new value posted? If so, use it instead.
+               if ( isset( $_POST['field_' . $field->id] ) ) {
+
+                       // This is sanitized via the filter below (based on the field type)
+                       $field->data->value = $_POST['field_' . $field->id];
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $field_value = isset( $field->data->value ) ? bp_unserialize_profile_field( $field->data->value ) : '';
-
</del><span class="cx" style="display: block; padding: 0 10px">                 /**
</span><span class="cx" style="display: block; padding: 0 10px">                 * Filters the XProfile field edit value.
</span><span class="cx" style="display: block; padding: 0 10px">                 *
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -619,7 +614,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                 * @param string $type        Type for the profile field.
</span><span class="cx" style="display: block; padding: 0 10px">                 * @param int    $id          ID for the profile field.
</span><span class="cx" style="display: block; padding: 0 10px">                 */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                return apply_filters( 'bp_get_the_profile_field_edit_value', $field_value, $field->type, $field->id );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         return apply_filters( 'bp_get_the_profile_field_edit_value', $field->data->value, $field->type, $field->id );
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -904,7 +899,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Return unserialized profile field data.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Return unserialized profile field data, and combine any array items into a
+ * comma-separated string.
</ins><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @since 1.0.0
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -913,7 +909,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> function bp_unserialize_profile_field( $value ) {
</span><span class="cx" style="display: block; padding: 0 10px">        if ( is_serialized($value) ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $field_value = maybe_unserialize($value);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $field_value = @unserialize($value);
</ins><span class="cx" style="display: block; padding: 0 10px">                 $field_value = implode( ', ', $field_value );
</span><span class="cx" style="display: block; padding: 0 10px">                return $field_value;
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span></span></pre>
</div>
</div>

</body>
</html>