PluginProbe
wpForo Forum / 3.1.6
wpForo Forum v3.1.6
3.1.6 3.1.5 3.1.4 3.1.2 3.1.1 3.1.0 3.0.9 3.0.8 3.0.7 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.2.0 1.3.0 1.3.1 1.4.0 1.4.1 1.4.10 1.4.11 1.4.12 1.4.13 All 138 releases
← All changes | classes/Forms.php +35 -14 3.0.73.1.6 View file →
@@ -982,15 +982,15 @@
982 982 case 'datetime':
983 983 $f['value'] = wpforo_date( $f['value'], 'datetime', false );
984 984 break;
985 985 case 'url':
986 - $f['value'] = sprintf( '<a href="%1$s" target="_blank" rel="nofollow">%2$s</a>', $f['value'], $f['value'] );
986 + $f['value'] = sprintf( '<a href="%1$s" target="_blank" rel="nofollow">%2$s</a>', esc_url( $f['value'] ), esc_html( $f['value'] ) );
987 987 break;
988 988 case 'email':
989 - $f['value'] = sprintf( '<a href="mailto:%1$s" rel="nofollow">%2$s</a>', $f['value'], $f['value'] );
989 + $f['value'] = sprintf( '<a href="mailto:%1$s" rel="nofollow">%2$s</a>', esc_attr( $f['value'] ), esc_html( $f['value'] ) );
990 990 break;
991 991 case 'tel':
992 - $f['value'] = sprintf( '<a href="tel:%1$s" rel="nofollow">%2$s</a>', $f['value'], $f['value'] );
992 + $f['value'] = sprintf( '<a href="tel:%1$s" rel="nofollow">%2$s</a>', esc_attr( $f['value'] ), esc_html( $f['value'] ) );
993 993 break;
994 994 case 'file':
995 995 if( ! empty( $f['value'] ) ) {
996 996 if( is_array( $f['value'] ) ) {
@@ -1005,17 +1005,17 @@
1005 1005 $extension = pathinfo( $f['value'], PATHINFO_EXTENSION );
1006 1006 if( wpforo_is_image( $extension ) ) {
1007 1007 $f['value'] = sprintf(
1008 1008 '<a href="%1$s" target="_blank" title="%2$s"><img src="%1$s" alt="%2$s" class="wpf-field-file-img" style="max-width:120px; max-height:120px"></a>',
1009 - $file_url,
1010 - $file_name
1009 + esc_url( $file_url ),
1010 + esc_attr( $file_name )
1011 1011 );
1012 1012 } elseif( wpforo_is_audio( $extension ) ) {
1013 - $f['value'] = sprintf( '<audio src="%1$s" controls title="%2$s"></audio>', $file_url, $file_name );
1013 + $f['value'] = sprintf( '<audio src="%1$s" controls title="%2$s"></audio>', esc_url( $file_url ), esc_attr( $file_name ) );
1014 1014 } elseif( wpforo_is_video( $extension ) ) {
1015 - $f['value'] = sprintf( '<video src="%1$s" controls title="%2$s"></video>', $file_url, $file_name );
1015 + $f['value'] = sprintf( '<video src="%1$s" controls title="%2$s"></video>', esc_url( $file_url ), esc_attr( $file_name ) );
1016 1016 } else {
1017 - $f['value'] = sprintf( '<a href="%s" target="_blank">%s</a>', $file_url, $file_name );
1017 + $f['value'] = sprintf( '<a href="%s" target="_blank">%s</a>', esc_url( $file_url ), esc_html( $file_name ) );
1018 1018 }
1019 1019 }
1020 1020 break;
1021 1021 case 'avatar':
@@ -1022,18 +1022,18 @@
1022 1022 $f['value'] = ( WPF()->usergroup->can( 'va' ) && wpforo_setting( 'profiles', 'avatars' ) ) ? WPF()->member->get_avatar_html( $f['value'], $userid ) : '';
1023 1023 break;
1024 1024 case 'color':
1025 1025 if( $f['value'] ) {
1026 - $f['value'] = '<input type="color" value="' . $f['value'] . '" disabled title="' . $f['value'] . '" style="min-width: 100px; min-height: 25px;">';
1026 + $f['value'] = '<input type="color" value="' . esc_attr( $f['value'] ) . '" disabled title="' . esc_attr( $f['value'] ) . '" style="min-width: 100px; min-height: 25px;">';
1027 1027 }
1028 1028 break;
1029 1029 }
1030 1030 switch( $f['name'] ) {
1031 1031 case 'skype':
1032 - $f['value'] = sprintf( '<a href="skype:%s?userinfo" rel="nofollow">%s</a>', $f['value'], $f['value'] );
1032 + $f['value'] = sprintf( '<a href="skype:%s?userinfo" rel="nofollow">%s</a>', esc_attr( $f['value'] ), esc_html( $f['value'] ) );
1033 1033 break;
1034 1034 case 'location':
1035 - $f['value'] = sprintf( '<a href="//maps.google.com/?q=%s" target="_blank" rel="nofollow">%s</a>', $f['value'], $f['value'] );
1035 + $f['value'] = sprintf( '<a href="//maps.google.com/?q=%s" target="_blank" rel="nofollow">%s</a>', esc_attr( $f['value'] ), esc_html( $f['value'] ) );
1036 1036 break;
1037 1037 case 'signature':
1038 1038 $f['value'] = wpforo_signature( $f['value'], [ 'echo' => 0 ] );
1039 1039 break;
@@ -1216,14 +1216,35 @@
1216 1216 $var = trim( (string) $var );
1217 1217 if( ! strlen( (string) $var ) ) return [];
1218 1218 }
1219 1219 if( is_serialized( $var ) ) {
1220 - $var = unserialize( $var );
1220 + // This value can come straight from the request: the field state is
1221 + // rebuilt from POST, and prepare_args() HTML-decodes it first, so an
1222 + // entity-encoded payload arrives here fully restored. Never
1223 + // instantiate classes, and never let one through as a value.
1224 + $decoded = unserialize( $var, [ 'allowed_classes' => false ] );
1225 + if( is_array( $decoded ) ) {
1226 + $var = $decoded;
1227 + } elseif( is_scalar( $decoded ) ) {
1228 + $var = [ $decoded ];
1229 + } else {
1230 + return [];
1231 + }
1221 1232 } elseif( is_scalar( $var ) && strpos( (string) $var, $sep ) !== false ) {
1222 1233 $var = explode( $sep, $var );
1223 1234 }
1224 -
1225 - return array_map( 'trim', (array) $var );
1235 +
1236 + // A multi-choice field value is a flat list of scalars. Only arrays and
1237 + // objects are dropped, which a crafted payload can nest here and which
1238 + // are a TypeError in trim() on PHP 8. Every other type is cast exactly
1239 + // as trim() used to coerce it, so null and bool values are unchanged.
1240 + $values = [];
1241 + foreach( (array) $var as $key => $value ) {
1242 + if( is_array( $value ) || is_object( $value ) ) continue;
1243 + $values[ $key ] = trim( (string) $value );
1244 + }
1245 +
1246 + return $values;
1226 1247 }
1227 1248
1228 1249 public function build_array_using_string_rows( $string, $regexp = '' ) {
1229 1250 if( is_scalar( $string ) ) {