| @@ -320,9 +320,9 @@ | ||
| 320 | 320 | $html .= esc_html( implode( ', ', $f['value'] ) ); |
| 321 | 321 | } else { |
| 322 | 322 | $f = $this->prepare_values( $f, WPF()->current_object['userid'] ); |
| 323 | 323 | $html .= '<div class="wpf-field-wrap">'; |
| 324 | - $html .= $f['value']; | |
| 324 | + $html .= ( is_scalar( $f['value'] ) && ! $this->is_display_value_safe_html( $f ) ) ? esc_html( (string) $f['value'] ) : $f['value']; | |
| 325 | 325 | $html .= '</div>'; |
| 326 | 326 | } |
| 327 | 327 | } else { |
| 328 | 328 | if( $default_values = wpforo_preg_grep_recursive( '#^\[.+?]$#isu', $f['values'] ) ) { |
| @@ -1315,8 +1315,24 @@ | ||
| 1315 | 1315 | |
| 1316 | 1316 | return $value; |
| 1317 | 1317 | } |
| 1318 | 1318 | |
| 1319 | + /** | |
| 1320 | + * Whether prepare_values()/esc_field() already turned $f['value'] into trusted, | |
| 1321 | + * pre-escaped HTML for this field type/name (so it must NOT be esc_html()'d again | |
| 1322 | + * before being echoed). | |
| 1323 | + * | |
| 1324 | + * @param array $f field arguments (after prepare_values()/esc_field()) | |
| 1325 | + * | |
| 1326 | + * @return bool | |
| 1327 | + */ | |
| 1328 | + public function is_display_value_safe_html( $f ) { | |
| 1329 | + $safe_types = [ 'url', 'email', 'tel', 'file', 'avatar', 'color', 'textarea', 'tinymce', 'datetime', 'html' ]; | |
| 1330 | + $safe_names = [ 'skype', 'location', 'signature', 'about' ]; | |
| 1331 | + | |
| 1332 | + return in_array( wpfval( $f, 'type' ), $safe_types, true ) || in_array( wpfval( $f, 'name' ), $safe_names, true ); | |
| 1333 | + } | |
| 1334 | + | |
| 1319 | 1335 | public function esc_field( $f ) { |
| 1320 | 1336 | if( wpfkey( $f, 'value' ) ) { |
| 1321 | 1337 | $f['value'] = wpforo_trim( $f['value'] ); |
| 1322 | 1338 | if( in_array( wpfval( $f, 'type' ), [ 'textarea', 'tinymce' ], true ) ) { |