PluginProbe
JetFormBuilder — Dynamic Blocks Form Builder / 3.6.6
JetFormBuilder — Dynamic Blocks Form Builder v3.6.6
3.6.6.1 3.6.6 3.6.5.4 3.6.5.3 3.6.5.2 3.6.5.1 3.6.5 3.6.4.2 3.6.4.1 3.6.4 3.6.3.1 3.6.3 3.6.2.2 3.6.2.1 3.6.2 3.6.1.1 3.6.1 3.6.0.1 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 All 134 releases
← All changes | includes/classes/tools.php +137 -8 3.6.0.1 → 3.6.6 View file →
@@ -105,11 +105,11 @@
105 105 *
106 106 * @return string
107 107 */
108 108 public static function sanitize_wysiwyg( $input ): string {
109 - $input = wp_kses_post( $input );
109 + $input = wp_specialchars_decode( stripslashes( $input ), ENT_COMPAT );
110 110
111 - return wp_specialchars_decode( stripslashes( $input ), ENT_COMPAT );
111 + return wp_kses_post( $input );
112 112 }
113 113
114 114 /**
115 115 * Return all taxonomies list to use in JS components
@@ -272,8 +272,110 @@
272 272 }
273 273 }
274 274
275 275 /**
276 + * Returns editable roles and ensures the core helper is loaded.
277 + *
278 + * @return array
279 + */
280 + public static function get_editable_roles_safe(): array {
281 + if ( ! function_exists( 'get_editable_roles' ) ) {
282 + require_once ABSPATH . 'wp-admin/includes/user.php';
283 + }
284 +
285 + if ( ! function_exists( 'get_editable_roles' ) ) {
286 + return array();
287 + }
288 +
289 + return get_editable_roles();
290 + }
291 +
292 + /**
293 + * Returns all registered roles without filtering by the current user's capabilities.
294 + *
295 + * @return array
296 + */
297 + public static function get_registered_roles_safe(): array {
298 + $wp_roles = wp_roles();
299 +
300 + if ( ! is_a( $wp_roles, \WP_Roles::class ) ) {
301 + return array();
302 + }
303 +
304 + return $wp_roles->roles ?? array();
305 + }
306 +
307 + /**
308 + * Returns auto-detected low-privilege roles that can be used as
309 + * a starting point for self-service role transitions.
310 + *
311 + * @return string[]
312 + */
313 + public static function get_default_self_promotable_roles(): array {
314 + $editable_roles = self::get_registered_roles_safe();
315 +
316 + if ( empty( $editable_roles ) ) {
317 + return array();
318 + }
319 +
320 + $roles = array();
321 +
322 + foreach ( array_keys( $editable_roles ) as $role ) {
323 + if ( self::is_safe_self_promotable_role( $role ) ) {
324 + $roles[] = $role;
325 + }
326 + }
327 +
328 + return array_values( array_unique( $roles ) );
329 + }
330 +
331 + public static function is_safe_self_promotable_role( string $role ): bool {
332 + if ( 'administrator' === $role ) {
333 + return false;
334 + }
335 +
336 + $wp_roles = wp_roles();
337 +
338 + if ( ! isset( $wp_roles->roles[ $role ] ) ) {
339 + return false;
340 + }
341 +
342 + $caps = array_filter( $wp_roles->roles[ $role ]['capabilities'] ?? array() );
343 +
344 + $dangerous_caps = array(
345 + 'activate_plugins',
346 + 'create_users',
347 + 'delete_users',
348 + 'edit_users',
349 + 'list_users',
350 + 'promote_users',
351 + 'remove_users',
352 + 'manage_options',
353 + 'edit_theme_options',
354 + 'switch_themes',
355 + 'install_plugins',
356 + 'update_plugins',
357 + 'delete_plugins',
358 + 'install_themes',
359 + 'update_themes',
360 + 'delete_themes',
361 + 'unfiltered_html',
362 + 'edit_others_posts',
363 + 'delete_others_posts',
364 + 'publish_posts',
365 + 'manage_categories',
366 + );
367 +
368 + foreach ( $dangerous_caps as $cap ) {
369 + if ( ! empty( $caps[ $cap ] ) ) {
370 + return false;
371 + }
372 + }
373 +
374 + return true;
375 + }
376 +
377 + /**
276 378 * Prepare passed array for using in JS options
277 379 *
278 380 * @param array $array
279 381 * @param null $value_key
@@ -438,8 +540,15 @@
438 540
439 541 $result = array();
440 542
441 543 foreach ( $source as $key => $value ) {
544 + $key = is_string( $key ) ? self::sanitize_array_key( $key ) : $key;
545 +
546 + // When sanitized keys collide, keep the first value.
547 + if ( array_key_exists( $key, $result ) ) {
548 + continue;
549 + }
550 +
442 551 $result[ $key ] = self::sanitize_recursive( $value );
443 552 }
444 553
445 554 return $result;
@@ -444,8 +553,20 @@
444 553
445 554 return $result;
446 555 }
447 556
557 + /**
558 + * Strips tags from an array key. Keys without tags stay unchanged,
559 + * preserving whitespace and percent-encoded sequences in field names.
560 + *
561 + * @param string $key
562 + *
563 + * @return string
564 + */
565 + public static function sanitize_array_key( string $key ): string {
566 + return false === strpos( $key, '<' ) ? $key : wp_strip_all_tags( $key, false );
567 + }
568 +
448 569 public static function maybe_recursive_sanitize( $source = null ) {
449 570 return self::sanitize_recursive( $source );
450 571 }
451 572
@@ -492,8 +613,14 @@
492 613 }
493 614
494 615 $result = array();
495 616 foreach ( $source as $key => $value ) {
617 + $key = is_string( $key ) ? self::sanitize_array_key( $key ) : $key;
618 +
619 + if ( array_key_exists( $key, $result ) ) {
620 + continue;
621 + }
622 +
496 623 $result[ $key ] = self::sanitize_recursive( $value );
497 624 }
498 625
499 626 return $result;
@@ -706,15 +833,17 @@
706 833 return false;
707 834 }
708 835
709 836 public static function get_array_of_user_roles( $settings ) {
710 - $user_roles = $settings ?? array();
711 - if ( ! empty( $user_roles ) ) {
712 - if ( is_string( $user_roles ) ) {
713 - $user_roles = array( $user_roles );
714 - }
837 + if ( is_string( $settings ) ) {
838 + return '' === $settings ? array() : array( $settings );
715 839 }
716 - return $user_roles;
840 +
841 + if ( ! is_array( $settings ) ) {
842 + return array();
843 + }
844 +
845 + return $settings;
717 846 }
718 847
719 848 public static function get_main_user_role_by_priority( $roles ): string {
720 849 if ( is_string( $roles ) ) {