$data Payload. * @return array */ public static function sanitize_deep( array $data ): array { $clean = array(); foreach ( $data as $key => $value ) { $safe_key = is_string( $key ) ? self::sanitize( $key ) : $key; if ( is_array( $value ) ) { $clean[ $safe_key ] = self::sanitize_deep( $value ); continue; } $clean[ $safe_key ] = is_string( $value ) ? self::sanitize( $value ) : $value; } return $clean; } /** * Whether a string is well-formed UTF-8. * * @param string $value Candidate. */ private static function is_valid( string $value ): bool { return (bool) preg_match( '//u', $value ); } /** * Width in bytes of the valid UTF-8 sequence starting at an offset, * or 0 when the byte at that offset cannot start a valid sequence. * * @param string $value Subject. * @param int $offset Start offset. * @param int $length Total length. */ private static function sequence_width( string $value, int $offset, int $length ): int { $byte = ord( $value[ $offset ] ); if ( $byte < 0x80 ) { return 1; } if ( $byte >= 0xC2 && $byte <= 0xDF ) { $width = 2; } elseif ( $byte >= 0xE0 && $byte <= 0xEF ) { $width = 3; } elseif ( $byte >= 0xF0 && $byte <= 0xF4 ) { $width = 4; } else { // Continuation byte, overlong lead (0xC0/0xC1), or out of range. return 0; } if ( $offset + $width > $length ) { return 0; } $candidate = substr( $value, $offset, $width ); // Rejects surrogates, overlongs, and bad continuations in one step. return self::is_valid( $candidate ) ? $width : 0; } }