• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • Examples
  • File List

E:/E/GEAMP/www/openbiz/openbiz/others/Zend/Validate/Hostname.php

00001 <?php
00025 require_once 'Zend/Validate/Abstract.php';
00026 
00030 require_once 'Zend/Validate/Ip.php';
00031 
00047 class Zend_Validate_Hostname extends Zend_Validate_Abstract
00048 {
00049     const INVALID                 = 'hostnameInvalid';
00050     const IP_ADDRESS_NOT_ALLOWED  = 'hostnameIpAddressNotAllowed';
00051     const UNKNOWN_TLD             = 'hostnameUnknownTld';
00052     const INVALID_DASH            = 'hostnameDashCharacter';
00053     const INVALID_HOSTNAME_SCHEMA = 'hostnameInvalidHostnameSchema';
00054     const UNDECIPHERABLE_TLD      = 'hostnameUndecipherableTld';
00055     const INVALID_HOSTNAME        = 'hostnameInvalidHostname';
00056     const INVALID_LOCAL_NAME      = 'hostnameInvalidLocalName';
00057     const LOCAL_NAME_NOT_ALLOWED  = 'hostnameLocalNameNotAllowed';
00058     const CANNOT_DECODE_PUNYCODE  = 'hostnameCannotDecodePunycode';
00059 
00063     protected $_messageTemplates = array(
00064         self::INVALID                 => "Invalid type given, value should be a string",
00065         self::IP_ADDRESS_NOT_ALLOWED  => "'%value%' appears to be an IP address, but IP addresses are not allowed",
00066         self::UNKNOWN_TLD             => "'%value%' appears to be a DNS hostname but cannot match TLD against known list",
00067         self::INVALID_DASH            => "'%value%' appears to be a DNS hostname but contains a dash (-) in an invalid position",
00068         self::INVALID_HOSTNAME_SCHEMA => "'%value%' appears to be a DNS hostname but cannot match against hostname schema for TLD '%tld%'",
00069         self::UNDECIPHERABLE_TLD      => "'%value%' appears to be a DNS hostname but cannot extract TLD part",
00070         self::INVALID_HOSTNAME        => "'%value%' does not match the expected structure for a DNS hostname",
00071         self::INVALID_LOCAL_NAME      => "'%value%' does not appear to be a valid local network name",
00072         self::LOCAL_NAME_NOT_ALLOWED  => "'%value%' appears to be a local network name but local network names are not allowed",
00073         self::CANNOT_DECODE_PUNYCODE  => "'%value%' appears to be a DNS hostname but the given punycode notation cannot be decoded"
00074     );
00075 
00079     protected $_messageVariables = array(
00080         'tld' => '_tld'
00081     );
00082 
00086     const ALLOW_DNS   = 1;
00087 
00091     const ALLOW_IP    = 2;
00092 
00096     const ALLOW_LOCAL = 4;
00097 
00101     const ALLOW_ALL   = 7;
00102 
00108     private $_validateIdn = true;
00109 
00115     private $_validateTld = true;
00116 
00122     protected $_allow;
00123 
00131     protected $_validTlds = array(
00132         'ac', 'ad', 'ae', 'aero', 'af', 'ag', 'ai', 'al', 'am', 'an', 'ao', 'aq', 'ar', 'arpa',
00133         'as', 'asia', 'at', 'au', 'aw', 'ax', 'az', 'ba', 'bb', 'bd', 'be', 'bf', 'bg', 'bh', 'bi',
00134         'biz', 'bj', 'bm', 'bn', 'bo', 'br', 'bs', 'bt', 'bv', 'bw', 'by', 'bz', 'ca', 'cat', 'cc',
00135         'cd', 'cf', 'cg', 'ch', 'ci', 'ck', 'cl', 'cm', 'cn', 'co', 'com', 'coop', 'cr', 'cu',
00136         'cv', 'cx', 'cy', 'cz', 'de', 'dj', 'dk', 'dm', 'do', 'dz', 'ec', 'edu', 'ee', 'eg', 'er',
00137         'es', 'et', 'eu', 'fi', 'fj', 'fk', 'fm', 'fo', 'fr', 'ga', 'gb', 'gd', 'ge', 'gf', 'gg',
00138         'gh', 'gi', 'gl', 'gm', 'gn', 'gov', 'gp', 'gq', 'gr', 'gs', 'gt', 'gu', 'gw', 'gy', 'hk',
00139         'hm', 'hn', 'hr', 'ht', 'hu', 'id', 'ie', 'il', 'im', 'in', 'info', 'int', 'io', 'iq',
00140         'ir', 'is', 'it', 'je', 'jm', 'jo', 'jobs', 'jp', 'ke', 'kg', 'kh', 'ki', 'km', 'kn', 'kp',
00141         'kr', 'kw', 'ky', 'kz', 'la', 'lb', 'lc', 'li', 'lk', 'lr', 'ls', 'lt', 'lu', 'lv', 'ly',
00142         'ma', 'mc', 'md', 'me', 'mg', 'mh', 'mil', 'mk', 'ml', 'mm', 'mn', 'mo', 'mobi', 'mp',
00143         'mq', 'mr', 'ms', 'mt', 'mu', 'museum', 'mv', 'mw', 'mx', 'my', 'mz', 'na', 'name', 'nc',
00144         'ne', 'net', 'nf', 'ng', 'ni', 'nl', 'no', 'np', 'nr', 'nu', 'nz', 'om', 'org', 'pa', 'pe',
00145         'pf', 'pg', 'ph', 'pk', 'pl', 'pm', 'pn', 'pr', 'pro', 'ps', 'pt', 'pw', 'py', 'qa', 're',
00146         'ro', 'rs', 'ru', 'rw', 'sa', 'sb', 'sc', 'sd', 'se', 'sg', 'sh', 'si', 'sj', 'sk', 'sl',
00147         'sm', 'sn', 'so', 'sr', 'st', 'su', 'sv', 'sy', 'sz', 'tc', 'td', 'tel', 'tf', 'tg', 'th',
00148         'tj', 'tk', 'tl', 'tm', 'tn', 'to', 'tp', 'tr', 'travel', 'tt', 'tv', 'tw', 'tz', 'ua',
00149         'ug', 'uk', 'um', 'us', 'uy', 'uz', 'va', 'vc', 've', 'vg', 'vi', 'vn', 'vu', 'wf', 'ws',
00150         'ye', 'yt', 'yu', 'za', 'zm', 'zw'
00151     );
00152 
00156     protected $_tld;
00157 
00208     protected $_validIdns = array(
00209         'AC'  => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$/iu'),
00210         'AR'  => array(1 => '/^[\x{002d}0-9a-zà-ãç-êìíñ-õü]{1,63}$/iu'),
00211         'AS'  => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźż]{1,63}$/iu'),
00212         'AT'  => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿœšž]{1,63}$/iu'),
00213         'BIZ' => 'Hostname/Biz.php',
00214         'BR'  => array(1 => '/^[\x{002d}0-9a-zà-ãçéíó-õúü]{1,63}$/iu'),
00215         'BV'  => array(1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'),
00216         'CAT' => array(1 => '/^[\x{002d}0-9a-z·àç-éíïòóúü]{1,63}$/iu'),
00217         'CH'  => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿœ]{1,63}$/iu'),
00218         'CL'  => array(1 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu'),
00219         'CN'  => 'Hostname/Cn.php',
00220         'COM' => 'Zend/Validate/Hostname/Com.php',
00221         'DE'  => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'),
00222         'DK'  => array(1 => '/^[\x{002d}0-9a-zäéöü]{1,63}$/iu'),
00223         'ES'  => array(1 => '/^[\x{002d}0-9a-zàáçèéíïñòóúü·]{1,63}$/iu'),
00224         'FI'  => array(1 => '/^[\x{002d}0-9a-zäåö]{1,63}$/iu'),
00225         'GR'  => array(1 => '/^[\x{002d}0-9a-zΆΈΉΊΌΎ-ΡΣ-ώἀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼῂῃῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲῳῴῶ-ῼ]{1,63}$/iu'),
00226         'HK'  => 'Zend/Validate/Hostname/Cn.php',
00227         'HU'  => array(1 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu'),
00228         'INFO'=> array(1 => '/^[\x{002d}0-9a-zäåæéöøü]{1,63}$/iu',
00229             2 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu',
00230             3 => '/^[\x{002d}0-9a-záæéíðóöúýþ]{1,63}$/iu',
00231             4 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu',
00232             5 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu',
00233             6 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu',
00234             7 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu',
00235             8 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu'),
00236         'IO'  => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'),
00237         'IS'  => array(1 => '/^[\x{002d}0-9a-záéýúíóþæöð]{1,63}$/iu'),
00238         'JP'  => 'Zend/Validate/Hostname/Jp.php',
00239         'KR'  => array(1 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu'),
00240         'LI'  => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿœ]{1,63}$/iu'),
00241         'LT'  => array(1 => '/^[\x{002d}0-9ąčęėįšųūž]{1,63}$/iu'),
00242         'MD'  => array(1 => '/^[\x{002d}0-9ăâîşţ]{1,63}$/iu'),
00243         'MUSEUM' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćċčďđēėęěğġģħīįıķĺļľłńņňŋōőœŕŗřśşšţťŧūůűųŵŷźżžǎǐǒǔ\x{01E5}\x{01E7}\x{01E9}\x{01EF}ə\x{0292}ẁẃẅỳ]{1,63}$/iu'),
00244         'NET' => 'Zend/Validate/Hostname/Com.php',
00245         'NO'  => array(1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'),
00246         'NU'  => 'Zend/Validate/Hostname/Com.php',
00247         'ORG' => array(1 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu',
00248             2 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu',
00249             3 => '/^[\x{002d}0-9a-záäåæéëíðóöøúüýþ]{1,63}$/iu',
00250             4 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu',
00251             5 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu',
00252             6 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu',
00253             7 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu'),
00254         'PE'  => array(1 => '/^[\x{002d}0-9a-zñáéíóúü]{1,63}$/iu'),
00255         'PL'  => array(1 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu',
00256             2 => '/^[\x{002d}а-ик-ш\x{0450}ѓѕјљњќџ]{1,63}$/iu',
00257             3 => '/^[\x{002d}0-9a-zâîăşţ]{1,63}$/iu',
00258             4 => '/^[\x{002d}0-9а-яё\x{04C2}]{1,63}$/iu',
00259             5 => '/^[\x{002d}0-9a-zàáâèéêìíîòóôùúûċġħż]{1,63}$/iu',
00260             6 => '/^[\x{002d}0-9a-zàäåæéêòóôöøü]{1,63}$/iu',
00261             7 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu',
00262             8 => '/^[\x{002d}0-9a-zàáâãçéêíòóôõúü]{1,63}$/iu',
00263             9 => '/^[\x{002d}0-9a-zâîăşţ]{1,63}$/iu',
00264             10=> '/^[\x{002d}0-9a-záäéíóôúýčďĺľňŕšťž]{1,63}$/iu',
00265             11=> '/^[\x{002d}0-9a-zçë]{1,63}$/iu',
00266             12=> '/^[\x{002d}0-9а-ик-шђјљњћџ]{1,63}$/iu',
00267             13=> '/^[\x{002d}0-9a-zćčđšž]{1,63}$/iu',
00268             14=> '/^[\x{002d}0-9a-zâçöûüğış]{1,63}$/iu',
00269             15=> '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu',
00270             16=> '/^[\x{002d}0-9a-zäõöüšž]{1,63}$/iu',
00271             17=> '/^[\x{002d}0-9a-zĉĝĥĵŝŭ]{1,63}$/iu',
00272             18=> '/^[\x{002d}0-9a-zâäéëîô]{1,63}$/iu',
00273             19=> '/^[\x{002d}0-9a-zàáâäåæçèéêëìíîïðñòôöøùúûüýćčłńřśš]{1,63}$/iu',
00274             20=> '/^[\x{002d}0-9a-zäåæõöøüšž]{1,63}$/iu',
00275             21=> '/^[\x{002d}0-9a-zàáçèéìíòóùú]{1,63}$/iu',
00276             22=> '/^[\x{002d}0-9a-zàáéíóöúüőű]{1,63}$/iu',
00277             23=> '/^[\x{002d}0-9ΐά-ώ]{1,63}$/iu',
00278             24=> '/^[\x{002d}0-9a-zàáâåæçèéêëðóôöøüþœ]{1,63}$/iu',
00279             25=> '/^[\x{002d}0-9a-záäéíóöúüýčďěňřšťůž]{1,63}$/iu',
00280             26=> '/^[\x{002d}0-9a-z·àçèéíïòóúü]{1,63}$/iu',
00281             27=> '/^[\x{002d}0-9а-ъьюя\x{0450}\x{045D}]{1,63}$/iu',
00282             28=> '/^[\x{002d}0-9а-яёіў]{1,63}$/iu',
00283             29=> '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu',
00284             30=> '/^[\x{002d}0-9a-záäåæéëíðóöøúüýþ]{1,63}$/iu',
00285             31=> '/^[\x{002d}0-9a-zàâæçèéêëîïñôùûüÿœ]{1,63}$/iu',
00286             32=> '/^[\x{002d}0-9а-щъыьэюяёєіїґ]{1,63}$/iu',
00287             33=> '/^[\x{002d}0-9א-ת]{1,63}$/iu'),
00288         'PR'  => array(1 => '/^[\x{002d}0-9a-záéíóúñäëïüöâêîôûàèùæçœãõ]{1,63}$/iu'),
00289         'PT'  => array(1 => '/^[\x{002d}0-9a-záàâãçéêíóôõú]{1,63}$/iu'),
00290         'RU'  => array(1 => '/^[\x{002d}0-9а-яё]{1,63}$/iu'),
00291         'SA'  => array(1 => '/^[\x{002d}.0-9\x{0621}-\x{063A}\x{0641}-\x{064A}\x{0660}-\x{0669}]{1,63}$/iu'),
00292         'SE'  => array(1 => '/^[\x{002d}0-9a-zäåéöü]{1,63}$/iu'),
00293         'SH'  => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'),
00294         'SJ'  => array(1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'),
00295         'TH'  => array(1 => '/^[\x{002d}0-9a-z\x{0E01}-\x{0E3A}\x{0E40}-\x{0E4D}\x{0E50}-\x{0E59}]{1,63}$/iu'),
00296         'TM'  => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$/iu'),
00297         'TW'  => 'Zend/Validate/Hostname/Cn.php',
00298         'TR'  => array(1 => '/^[\x{002d}0-9a-zğıüşöç]{1,63}$/iu'),
00299         'VE'  => array(1 => '/^[\x{002d}0-9a-záéíóúüñ]{1,63}$/iu'),
00300         'VN'  => array(1 => '/^[ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚÝàáâãèéêìíòóôõùúýĂăĐđĨĩŨũƠơƯư\x{1EA0}-\x{1EF9}]{1,63}$/iu'),
00301         'ایران' => array(1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'),
00302         '中国' => 'Zend/Validate/Hostname/Cn.php',
00303         '公司' => 'Zend/Validate/Hostname/Cn.php',
00304         '网络' => 'Zend/Validate/Hostname/Cn.php'
00305     );
00306 
00307     protected $_idnLength = array(
00308         'BIZ' => array(5 => 17, 11 => 15, 12 => 20),
00309         'CN'  => array(1 => 20),
00310         'COM' => array(3 => 17, 5 => 20),
00311         'HK'  => array(1 => 15),
00312         'INFO'=> array(4 => 17),
00313         'KR'  => array(1 => 17),
00314         'NET' => array(3 => 17, 5 => 20),
00315         'ORG' => array(6 => 17),
00316         'TW'  => array(1 => 20),
00317         'ایران' => array(1 => 30),
00318         '中国' => array(1 => 20),
00319         '公司' => array(1 => 20),
00320         '网络' => array(1 => 20),
00321     );
00322 
00333     public function __construct($allow = self::ALLOW_DNS, $validateIdn = true, $validateTld = true, Zend_Validate_Ip $ipValidator = null)
00334     {
00335         // Set allow options
00336         $this->setAllow($allow);
00337 
00338         // Set validation options
00339         $this->_validateIdn = $validateIdn;
00340         $this->_validateTld = $validateTld;
00341 
00342         $this->setIpValidator($ipValidator);
00343     }
00344 
00349     public function setIpValidator(Zend_Validate_Ip $ipValidator = null)
00350     {
00351         if ($ipValidator === null) {
00352             $ipValidator = new Zend_Validate_Ip();
00353         }
00354         $this->_ipValidator = $ipValidator;
00355     }
00356 
00362     public function getAllow()
00363     {
00364         return $this->_allow;
00365     }
00366 
00373     public function setAllow($allow)
00374     {
00375         $this->_allow = $allow;
00376         return $this;
00377     }
00378 
00386     public function setValidateIdn ($allowed)
00387     {
00388         $this->_validateIdn = (bool) $allowed;
00389     }
00390 
00398     public function setValidateTld ($allowed)
00399     {
00400         $this->_validateTld = (bool) $allowed;
00401     }
00402 
00412     public function isValid($value)
00413     {
00414         if (!is_string($value)) {
00415             $this->_error(self::INVALID);
00416             return false;
00417         }
00418 
00419         $this->_setValue($value);
00420 
00421         // Check input against IP address schema
00422         if (preg_match('/^[0-9.a-e:.]*$/i', $value) &&
00423             $this->_ipValidator->setTranslator($this->getTranslator())->isValid($value)) {
00424             if (!($this->_allow & self::ALLOW_IP)) {
00425                 $this->_error(self::IP_ADDRESS_NOT_ALLOWED);
00426                 return false;
00427             } else {
00428                 return true;
00429             }
00430         }
00431 
00432         // Check input against DNS hostname schema
00433         $domainParts = explode('.', $value);
00434         if ((count($domainParts) > 1) && (strlen($value) >= 4) && (strlen($value) <= 254)) {
00435             $status = false;
00436 
00437             $origenc = iconv_get_encoding('internal_encoding');
00438             iconv_set_encoding('internal_encoding', 'UTF-8');
00439             do {
00440                 // First check TLD
00441                 $matches = array();
00442                 if (preg_match('/([^.]{2,10})$/i', end($domainParts), $matches) ||
00443                     (end($domainParts) == 'ایران') || (end($domainParts) == '中国') ||
00444                     (end($domainParts) == '公司') || (end($domainParts) == '网络')) {
00445 
00446                     reset($domainParts);
00447 
00448                     // Hostname characters are: *(label dot)(label dot label); max 254 chars
00449                     // label: id-prefix [*ldh{61} id-prefix]; max 63 chars
00450                     // id-prefix: alpha / digit
00451                     // ldh: alpha / digit / dash
00452 
00453                     // Match TLD against known list
00454                     $this->_tld = strtolower($matches[1]);
00455                     if ($this->_validateTld) {
00456                         if (!in_array($this->_tld, $this->_validTlds)) {
00457                             $this->_error(self::UNKNOWN_TLD);
00458                             $status = false;
00459                             break;
00460                         }
00461                     }
00462 
00468                     $regexChars = array(0 => '/^[a-z0-9\x2d]{1,63}$/i');
00469                     if ($this->_validateIdn &&  isset($this->_validIdns[strtoupper($this->_tld)])) {
00470                         if (is_string($this->_validIdns[strtoupper($this->_tld)])) {
00471                             $regexChars += include($this->_validIdns[strtoupper($this->_tld)]);
00472                         } else {
00473                             $regexChars += $this->_validIdns[strtoupper($this->_tld)];
00474                         }
00475                     }
00476 
00477                     // Check each hostname part
00478                     $valid = true;
00479                     foreach ($domainParts as $domainPart) {
00480 
00481                         // Decode Punycode domainnames to IDN
00482                         if (strpos($domainPart, 'xn--') === 0) {
00483                             $domainPart = $this->decodePunycode(substr($domainPart, 4));
00484                             if ($domainPart === false) {
00485                                 return false;
00486                             }
00487                         }
00488 
00489                         // Check dash (-) does not start, end or appear in 3rd and 4th positions
00490                         if ((strpos($domainPart, '-') === 0)
00491                             || ((strlen($domainPart) > 2) && (strpos($domainPart, '-', 2) == 2) && (strpos($domainPart, '-', 3) == 3))
00492                             || (strpos($domainPart, '-') === (strlen($domainPart) - 1))) {
00493                             $this->_error(self::INVALID_DASH);
00494                             $status = false;
00495                             break 2;
00496                         }
00497 
00498                         // Check each domain part
00499                         $check = false;
00500                         foreach($regexChars as $regexKey => $regexChar) {
00501                             $status = @preg_match($regexChar, $domainPart);
00502                             if ($status === false) {
00503                                 iconv_set_encoding('internal_encoding', $origenc);
00504                                 require_once 'Zend/Validate/Exception.php';
00505                                 throw new Zend_Validate_Exception('Internal error: DNS validation failed');
00506                             } elseif ($status !== 0) {
00507                                 $length = 63;
00508                                 if (array_key_exists(strtoupper($this->_tld), $this->_idnLength)
00509                                     && (array_key_exists($regexKey, $this->_idnLength[strtoupper($this->_tld)]))) {
00510                                     $length = $this->_idnLength[strtoupper($this->_tld)];
00511                                 }
00512 
00513                                 if (iconv_strlen($domainPart, 'UTF-8') > $length) {
00514                                     $this->_error(self::INVALID_HOSTNAME);
00515                                 } else {
00516                                     $check = true;
00517                                     break 2;
00518                                 }
00519                             }
00520                         }
00521 
00522                         if (!$check) {
00523                             $valid = false;
00524                         }
00525                     }
00526 
00527                     // If all labels didn't match, the hostname is invalid
00528                     if (!$valid) {
00529                         $this->_error(self::INVALID_HOSTNAME_SCHEMA);
00530                         $status = false;
00531                     }
00532 
00533                 } else {
00534                     // Hostname not long enough
00535                     $this->_error(self::UNDECIPHERABLE_TLD);
00536                     $status = false;
00537                 }
00538             } while (false);
00539 
00540             iconv_set_encoding('internal_encoding', $origenc);
00541             // If the input passes as an Internet domain name, and domain names are allowed, then the hostname
00542             // passes validation
00543             if ($status && ($this->_allow & self::ALLOW_DNS)) {
00544                 return true;
00545             }
00546         } else {
00547             $this->_error(self::INVALID_HOSTNAME);
00548         }
00549 
00550         // Check input against local network name schema; last chance to pass validation
00551         $regexLocal = '/^(([a-zA-Z0-9\x2d]{1,63}\x2e)*[a-zA-Z0-9\x2d]{1,63}){1,254}$/';
00552         $status = @preg_match($regexLocal, $value);
00553         if (false === $status) {
00558             require_once 'Zend/Validate/Exception.php';
00559             throw new Zend_Validate_Exception('Internal error: local network name validation failed');
00560         }
00561 
00562         // If the input passes as a local network name, and local network names are allowed, then the
00563         // hostname passes validation
00564         $allowLocal = $this->_allow & self::ALLOW_LOCAL;
00565         if ($status && $allowLocal) {
00566             return true;
00567         }
00568 
00569         // If the input does not pass as a local network name, add a message
00570         if (!$status) {
00571             $this->_error(self::INVALID_LOCAL_NAME);
00572         }
00573 
00574         // If local network names are not allowed, add a message
00575         if ($status && !$allowLocal) {
00576             $this->_error(self::LOCAL_NAME_NOT_ALLOWED);
00577         }
00578 
00579         return false;
00580     }
00581 
00589     protected function decodePunycode($encoded)
00590     {
00591         $found = preg_match('/([^a-z0-9\x2d]{1,10})$/i', $encoded);
00592         if (empty($encoded) || ($found > 0)) {
00593             // no punycode encoded string, return as is
00594             $this->_error(self::CANNOT_DECODE_PUNYCODE);
00595             return false;
00596         }
00597 
00598         $separator = strrpos($encoded, '-');
00599         if ($separator > 0) {
00600             for ($x = 0; $x < $separator; ++$x) {
00601                 // prepare decoding matrix
00602                 $decoded[] = ord($encoded[$x]);
00603             }
00604         } else {
00605             $this->_error(self::CANNOT_DECODE_PUNYCODE);
00606             return false;
00607         }
00608 
00609         $lengthd = count($decoded);
00610         $lengthe = strlen($encoded);
00611 
00612         // decoding
00613         $init  = true;
00614         $base  = 72;
00615         $index = 0;
00616         $char  = 0x80;
00617 
00618         for ($indexe = ($separator) ? ($separator + 1) : 0; $indexe < $lengthe; ++$lengthd) {
00619             for ($old_index = $index, $pos = 1, $key = 36; 1 ; $key += 36) {
00620                 $hex   = ord($encoded[$indexe++]);
00621                 $digit = ($hex - 48 < 10) ? $hex - 22
00622                        : (($hex - 65 < 26) ? $hex - 65
00623                        : (($hex - 97 < 26) ? $hex - 97
00624                        : 36));
00625 
00626                 $index += $digit * $pos;
00627                 $tag    = ($key <= $base) ? 1 : (($key >= $base + 26) ? 26 : ($key - $base));
00628                 if ($digit < $tag) {
00629                     break;
00630                 }
00631 
00632                 $pos = (int) ($pos * (36 - $tag));
00633             }
00634 
00635             $delta   = intval($init ? (($index - $old_index) / 700) : (($index - $old_index) / 2));
00636             $delta  += intval($delta / ($lengthd + 1));
00637             for ($key = 0; $delta > 910 / 2; $key += 36) {
00638                 $delta = intval($delta / 35);
00639             }
00640 
00641             $base   = intval($key + 36 * $delta / ($delta + 38));
00642             $init   = false;
00643             $char  += (int) ($index / ($lengthd + 1));
00644             $index %= ($lengthd + 1);
00645             if ($lengthd > 0) {
00646                 for ($i = $lengthd; $i > $index; $i--) {
00647                     $decoded[$i] = $decoded[($i - 1)];
00648                 }
00649             }
00650 
00651             $decoded[$index++] = $char;
00652         }
00653 
00654         // convert decoded ucs4 to utf8 string
00655         foreach ($decoded as $key => $value) {
00656             if ($value < 128) {
00657                 $decoded[$key] = chr($value);
00658             } elseif ($value < (1 << 11)) {
00659                 $decoded[$key]  = chr(192 + ($value >> 6));
00660                 $decoded[$key] .= chr(128 + ($value & 63));
00661             } elseif ($value < (1 << 16)) {
00662                 $decoded[$key]  = chr(224 + ($value >> 12));
00663                 $decoded[$key] .= chr(128 + (($value >> 6) & 63));
00664                 $decoded[$key] .= chr(128 + ($value & 63));
00665             } elseif ($value < (1 << 21)) {
00666                 $decoded[$key]  = chr(240 + ($value >> 18));
00667                 $decoded[$key] .= chr(128 + (($value >> 12) & 63));
00668                 $decoded[$key] .= chr(128 + (($value >> 6) & 63));
00669                 $decoded[$key] .= chr(128 + ($value & 63));
00670             } else {
00671                 $this->_error(self::CANNOT_DECODE_PUNYCODE);
00672                 return false;
00673             }
00674         }
00675 
00676         return implode($decoded);
00677     }
00678 }

Generated on Thu Apr 19 2012 17:01:18 for openbiz by  doxygen 1.7.2