| @@ -540,8 +540,15 @@ | ||
| 540 | 540 | |
| 541 | 541 | $result = array(); |
| 542 | 542 | |
| 543 | 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 | + | |
| 544 | 551 | $result[ $key ] = self::sanitize_recursive( $value ); |
| 545 | 552 | } |
| 546 | 553 | |
| 547 | 554 | return $result; |
| @@ -546,8 +553,20 @@ | ||
| 546 | 553 | |
| 547 | 554 | return $result; |
| 548 | 555 | } |
| 549 | 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 | + | |
| 550 | 569 | public static function maybe_recursive_sanitize( $source = null ) { |
| 551 | 570 | return self::sanitize_recursive( $source ); |
| 552 | 571 | } |
| 553 | 572 | |
| @@ -594,8 +613,14 @@ | ||
| 594 | 613 | } |
| 595 | 614 | |
| 596 | 615 | $result = array(); |
| 597 | 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 | + | |
| 598 | 623 | $result[ $key ] = self::sanitize_recursive( $value ); |
| 599 | 624 | } |
| 600 | 625 | |
| 601 | 626 | return $result; |