/** * Attempts to return a concrete IDNA instance for either php4 or php5, * only creating a new instance if no IDNA instance with the same * parameters currently exists. * * @param array $params Set of paramaters * @return object IDNA The newly created concrete Log instance, or an * false on an error. * @access public */ function &singleton($params = array()) { static $instances; if (!isset($instances)) { $instances = array(); } $signature = serialize($params); if (!isset($instances[$signature])) { $instances[$signature] =& Net_IDNA::getInstance($params); } return $instances[$signature]; }
/** * Determine if given domain or address literal is valid * eg for use in JIDs and URLs. Does not check if the domain * exists! * * @param string $domain * @return boolean valid or not */ function common_valid_domain($domain) { $octet = "(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])"; $ipv4 = "(?:{$octet}(?:\\.{$octet}){3})"; if (preg_match("/^{$ipv4}\$/u", $domain)) { return true; } $group = "(?:[0-9a-f]{1,4})"; $ipv6 = "(?:\\[({$group}(?::{$group}){0,7})?(::)?({$group}(?::{$group}){0,7})?\\])"; // http://tools.ietf.org/html/rfc3513#section-2.2 if (preg_match("/^{$ipv6}\$/ui", $domain, $matches)) { $before = explode(":", $matches[1]); $zeroes = $matches[2]; $after = explode(":", $matches[3]); if ($zeroes) { $min = 0; $max = 7; } else { $min = 1; $max = 8; } $explicit = count($before) + count($after); if ($explicit < $min || $explicit > $max) { return false; } return true; } try { require_once "Net/IDNA.php"; $idn = Net_IDNA::getInstance(); $domain = $idn->encode($domain); } catch (Exception $e) { return false; } $subdomain = "(?:[a-z0-9][a-z0-9-]*)"; // @fixme $fqdn = "(?:{$subdomain}(?:\\.{$subdomain})*\\.?)"; return preg_match("/^{$fqdn}\$/ui", $domain); }
<?php header('Content-Type: text/html; charset=UTF-8'); require 'Net/IDNA.php'; $idn = Net_IDNA::getInstance(); if (isset($_REQUEST['encode'])) { $decoded = isset($_REQUEST['decoded']) ? $_REQUEST['decoded'] : ''; try { $encoded = $idn->encode($decoded); } catch (Exception $e) { /* just swallow */ } } if (isset($_REQUEST['decode'])) { $encoded = isset($_REQUEST['encoded']) ? $_REQUEST['encoded'] : ''; try { $decoded = $idn->decode($encoded); } catch (Exception $e) { /* just swallow */ } } if (!isset($encoded)) { $encoded = ''; } if (!isset($decoded)) { $decoded = ''; } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html>
/** * Validate an email * * @param string $email email to validate * @param mixed boolean (BC) $check_domain Check or not if the domain exists * array $options associative array of options * 'check_domain' boolean Check or not if the domain exists * 'use_rfc822' boolean Apply the full RFC822 grammar * * Ex. * $options = array( * 'check_domain' => 'true', * 'fullTLDValidation' => 'true', * 'use_rfc822' => 'true', * 'VALIDATE_GTLD_EMAILS' => 'true', * 'VALIDATE_CCTLD_EMAILS' => 'true', * 'VALIDATE_ITLD_EMAILS' => 'true', * ); * * @return boolean true if valid email, false if not * * @access public */ function email($email, $options = null) { $check_domain = false; $use_rfc822 = false; if (is_bool($options)) { $check_domain = $options; } elseif (is_array($options)) { extract($options); } /** * Check for IDN usage so we can encode the domain as Punycode * before continuing. */ $hasIDNA = false; if (@(include_once 'Net/IDNA.php')) { $hasIDNA = true; } if ($hasIDNA === true) { if (strpos($email, '@') !== false) { list($name, $domain) = explode('@', $email, 2); // Check if the domain contains characters > 127 which means // it's an idn domain name. $chars = count_chars($domain, 1); if (!empty($chars) && max(array_keys($chars)) > 127) { $idna =& Net_IDNA::singleton(); $domain = $idna->encode($domain); } $email = "{$name}@{$domain}"; } } /** * @todo Fix bug here.. even if it passes this, it won't be passing * The regular expression below */ if (isset($fullTLDValidation)) { //$valid = Validate::_fullTLDValidation($email, $fullTLDValidation); $valid = Validate::_fullTLDValidation($email, $options); if (!$valid) { return false; } } // the base regexp for address $regex = '&^(?: # recipient: ("\\s*(?:[^"\\f\\n\\r\\t\\v\\b\\s]+\\s*)+")| #1 quoted name ([-\\w!\\#\\$%\\&\'*+~/^`|{}]+(?:\\.[-\\w!\\#\\$%\\&\'*+~/^`|{}]+)*)) #2 OR dot-atom @(((\\[)? #3 domain, 4 as IPv4, 5 optionally bracketed (?:(?:(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:[0-1]?[0-9]?[0-9]))\\.){3} (?:(?:25[0-5])|(?:2[0-4][0-9])|(?:[0-1]?[0-9]?[0-9]))))(?(5)\\])| ((?:[a-z0-9](?:[-a-z0-9]*[a-z0-9])?\\.)*[a-z0-9](?:[-a-z0-9]*[a-z0-9])?) #6 domain as hostname \\.((?:([^- ])[-a-z]*[-a-z]))) #7 TLD $&xi'; //checks if exists the domain (MX or A) if ($use_rfc822 ? Validate::__emailRFC822($email, $options) : preg_match($regex, $email)) { if ($check_domain && function_exists('checkdnsrr')) { list($account, $domain) = explode('@', $email); if (checkdnsrr($domain, 'MX') || checkdnsrr($domain, 'A')) { return true; } return false; } return true; } return false; }
/** * Echo hex representation of UCS4 sequence. * * @param array $input UCS4 sequence * @param boolean $include_bit Include bitmask in output * @return void * @static * @access private */ private static function _showHex($input, $include_bit = false) { foreach ($input as $k => $v) { echo '[', $k, '] => ', sprintf('%X', $v); if ($include_bit) { echo ' (', Net_IDNA::_showBitmask($v), ')'; } echo "\n"; } }