Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/zend/Zend/Validate/Hostname.php
Go to the documentation of this file.
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 
00110     protected $_validTlds = array(
00111         'ac', 'ad', 'ae', 'aero', 'af', 'ag', 'ai', 'al', 'am', 'an', 'ao', 'aq', 'ar', 'arpa',
00112         'as', 'asia', 'at', 'au', 'aw', 'ax', 'az', 'ba', 'bb', 'bd', 'be', 'bf', 'bg', 'bh', 'bi',
00113         'biz', 'bj', 'bm', 'bn', 'bo', 'br', 'bs', 'bt', 'bv', 'bw', 'by', 'bz', 'ca', 'cat', 'cc',
00114         'cd', 'cf', 'cg', 'ch', 'ci', 'ck', 'cl', 'cm', 'cn', 'co', 'com', 'coop', 'cr', 'cu',
00115         'cv', 'cx', 'cy', 'cz', 'de', 'dj', 'dk', 'dm', 'do', 'dz', 'ec', 'edu', 'ee', 'eg', 'er',
00116         'es', 'et', 'eu', 'fi', 'fj', 'fk', 'fm', 'fo', 'fr', 'ga', 'gb', 'gd', 'ge', 'gf', 'gg',
00117         'gh', 'gi', 'gl', 'gm', 'gn', 'gov', 'gp', 'gq', 'gr', 'gs', 'gt', 'gu', 'gw', 'gy', 'hk',
00118         'hm', 'hn', 'hr', 'ht', 'hu', 'id', 'ie', 'il', 'im', 'in', 'info', 'int', 'io', 'iq',
00119         'ir', 'is', 'it', 'je', 'jm', 'jo', 'jobs', 'jp', 'ke', 'kg', 'kh', 'ki', 'km', 'kn', 'kp',
00120         'kr', 'kw', 'ky', 'kz', 'la', 'lb', 'lc', 'li', 'lk', 'lr', 'ls', 'lt', 'lu', 'lv', 'ly',
00121         'ma', 'mc', 'md', 'me', 'mg', 'mh', 'mil', 'mk', 'ml', 'mm', 'mn', 'mo', 'mobi', 'mp',
00122         'mq', 'mr', 'ms', 'mt', 'mu', 'museum', 'mv', 'mw', 'mx', 'my', 'mz', 'na', 'name', 'nc',
00123         'ne', 'net', 'nf', 'ng', 'ni', 'nl', 'no', 'np', 'nr', 'nu', 'nz', 'om', 'org', 'pa', 'pe',
00124         'pf', 'pg', 'ph', 'pk', 'pl', 'pm', 'pn', 'pr', 'pro', 'ps', 'pt', 'pw', 'py', 'qa', 're',
00125         'ro', 'rs', 'ru', 'rw', 'sa', 'sb', 'sc', 'sd', 'se', 'sg', 'sh', 'si', 'sj', 'sk', 'sl',
00126         'sm', 'sn', 'so', 'sr', 'st', 'su', 'sv', 'sy', 'sz', 'tc', 'td', 'tel', 'tf', 'tg', 'th',
00127         'tj', 'tk', 'tl', 'tm', 'tn', 'to', 'tp', 'tr', 'travel', 'tt', 'tv', 'tw', 'tz', 'ua',
00128         'ug', 'uk', 'um', 'us', 'uy', 'uz', 'va', 'vc', 've', 'vg', 'vi', 'vn', 'vu', 'wf', 'ws',
00129         'ye', 'yt', 'yu', 'za', 'zm', 'zw'
00130     );
00131 
00135     protected $_tld;
00136 
00187     protected $_validIdns = array(
00188         'AC'  => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$/iu'),
00189         'AR'  => array(1 => '/^[\x{002d}0-9a-zà-ãç-êìíñ-õü]{1,63}$/iu'),
00190         'AS'  => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźż]{1,63}$/iu'),
00191         'AT'  => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿœšž]{1,63}$/iu'),
00192         'BIZ' => 'Hostname/Biz.php',
00193         'BR'  => array(1 => '/^[\x{002d}0-9a-zà-ãçéíó-õúü]{1,63}$/iu'),
00194         'BV'  => array(1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'),
00195         'CAT' => array(1 => '/^[\x{002d}0-9a-z·àç-éíïòóúü]{1,63}$/iu'),
00196         'CH'  => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿœ]{1,63}$/iu'),
00197         'CL'  => array(1 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu'),
00198         'CN'  => 'Hostname/Cn.php',
00199         'COM' => 'Zend/Validate/Hostname/Com.php',
00200         'DE'  => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'),
00201         'DK'  => array(1 => '/^[\x{002d}0-9a-zäéöü]{1,63}$/iu'),
00202         'ES'  => array(1 => '/^[\x{002d}0-9a-zàáçèéíïñòóúü·]{1,63}$/iu'),
00203         'EU'  => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿ]{1,63}$/iu',
00204             2 => '/^[\x{002d}0-9a-zāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĺļľŀłńņňʼnŋōŏőœŕŗřśŝšťŧũūŭůűųŵŷźżž]{1,63}$/iu',
00205             3 => '/^[\x{002d}0-9a-zșț]{1,63}$/iu',
00206             4 => '/^[\x{002d}0-9a-zΐάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ]{1,63}$/iu',
00207             5 => '/^[\x{002d}0-9a-zабвгдежзийклмнопрстуфхцчшщъыьэюя]{1,63}$/iu',
00208             6 => '/^[\x{002d}0-9a-zἀ-ἇἐ-ἕἠ-ἧἰ-ἷὀ-ὅὐ-ὗὠ-ὧὰ-ώᾀ-ᾇᾐ-ᾗᾠ-ᾧᾰ-ᾴᾶᾷῂῃῄῆῇῐ-ΐῖῗῠ-ῧῲῳῴῶῷ]{1,63}$/iu'),
00209         'FI'  => array(1 => '/^[\x{002d}0-9a-zäåö]{1,63}$/iu'),
00210         'GR'  => array(1 => '/^[\x{002d}0-9a-zΆΈΉΊΌΎ-ΡΣ-ώἀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼῂῃῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲῳῴῶ-ῼ]{1,63}$/iu'),
00211         'HK'  => 'Zend/Validate/Hostname/Cn.php',
00212         'HU'  => array(1 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu'),
00213         'INFO'=> array(1 => '/^[\x{002d}0-9a-zäåæéöøü]{1,63}$/iu',
00214             2 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu',
00215             3 => '/^[\x{002d}0-9a-záæéíðóöúýþ]{1,63}$/iu',
00216             4 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu',
00217             5 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu',
00218             6 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu',
00219             7 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu',
00220             8 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu'),
00221         'IO'  => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'),
00222         'IS'  => array(1 => '/^[\x{002d}0-9a-záéýúíóþæöð]{1,63}$/iu'),
00223         'JP'  => 'Zend/Validate/Hostname/Jp.php',
00224         'KR'  => array(1 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu'),
00225         'LI'  => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿœ]{1,63}$/iu'),
00226         'LT'  => array(1 => '/^[\x{002d}0-9ąčęėįšųūž]{1,63}$/iu'),
00227         'MD'  => array(1 => '/^[\x{002d}0-9ăâîşţ]{1,63}$/iu'),
00228         'MUSEUM' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćċčďđēėęěğġģħīįıķĺļľłńņňŋōőœŕŗřśşšţťŧūůűųŵŷźżžǎǐǒǔ\x{01E5}\x{01E7}\x{01E9}\x{01EF}ə\x{0292}ẁẃẅỳ]{1,63}$/iu'),
00229         'NET' => 'Zend/Validate/Hostname/Com.php',
00230         'NO'  => array(1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'),
00231         'NU'  => 'Zend/Validate/Hostname/Com.php',
00232         'ORG' => array(1 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu',
00233             2 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu',
00234             3 => '/^[\x{002d}0-9a-záäåæéëíðóöøúüýþ]{1,63}$/iu',
00235             4 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu',
00236             5 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu',
00237             6 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu',
00238             7 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu'),
00239         'PE'  => array(1 => '/^[\x{002d}0-9a-zñáéíóúü]{1,63}$/iu'),
00240         'PL'  => array(1 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu',
00241             2 => '/^[\x{002d}а-ик-ш\x{0450}ѓѕјљњќџ]{1,63}$/iu',
00242             3 => '/^[\x{002d}0-9a-zâîăşţ]{1,63}$/iu',
00243             4 => '/^[\x{002d}0-9а-яё\x{04C2}]{1,63}$/iu',
00244             5 => '/^[\x{002d}0-9a-zàáâèéêìíîòóôùúûċġħż]{1,63}$/iu',
00245             6 => '/^[\x{002d}0-9a-zàäåæéêòóôöøü]{1,63}$/iu',
00246             7 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu',
00247             8 => '/^[\x{002d}0-9a-zàáâãçéêíòóôõúü]{1,63}$/iu',
00248             9 => '/^[\x{002d}0-9a-zâîăşţ]{1,63}$/iu',
00249             10=> '/^[\x{002d}0-9a-záäéíóôúýčďĺľňŕšťž]{1,63}$/iu',
00250             11=> '/^[\x{002d}0-9a-zçë]{1,63}$/iu',
00251             12=> '/^[\x{002d}0-9а-ик-шђјљњћџ]{1,63}$/iu',
00252             13=> '/^[\x{002d}0-9a-zćčđšž]{1,63}$/iu',
00253             14=> '/^[\x{002d}0-9a-zâçöûüğış]{1,63}$/iu',
00254             15=> '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu',
00255             16=> '/^[\x{002d}0-9a-zäõöüšž]{1,63}$/iu',
00256             17=> '/^[\x{002d}0-9a-zĉĝĥĵŝŭ]{1,63}$/iu',
00257             18=> '/^[\x{002d}0-9a-zâäéëîô]{1,63}$/iu',
00258             19=> '/^[\x{002d}0-9a-zàáâäåæçèéêëìíîïðñòôöøùúûüýćčłńřśš]{1,63}$/iu',
00259             20=> '/^[\x{002d}0-9a-zäåæõöøüšž]{1,63}$/iu',
00260             21=> '/^[\x{002d}0-9a-zàáçèéìíòóùú]{1,63}$/iu',
00261             22=> '/^[\x{002d}0-9a-zàáéíóöúüőű]{1,63}$/iu',
00262             23=> '/^[\x{002d}0-9ΐά-ώ]{1,63}$/iu',
00263             24=> '/^[\x{002d}0-9a-zàáâåæçèéêëðóôöøüþœ]{1,63}$/iu',
00264             25=> '/^[\x{002d}0-9a-záäéíóöúüýčďěňřšťůž]{1,63}$/iu',
00265             26=> '/^[\x{002d}0-9a-z·àçèéíïòóúü]{1,63}$/iu',
00266             27=> '/^[\x{002d}0-9а-ъьюя\x{0450}\x{045D}]{1,63}$/iu',
00267             28=> '/^[\x{002d}0-9а-яёіў]{1,63}$/iu',
00268             29=> '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu',
00269             30=> '/^[\x{002d}0-9a-záäåæéëíðóöøúüýþ]{1,63}$/iu',
00270             31=> '/^[\x{002d}0-9a-zàâæçèéêëîïñôùûüÿœ]{1,63}$/iu',
00271             32=> '/^[\x{002d}0-9а-щъыьэюяёєіїґ]{1,63}$/iu',
00272             33=> '/^[\x{002d}0-9א-ת]{1,63}$/iu'),
00273         'PR'  => array(1 => '/^[\x{002d}0-9a-záéíóúñäëïüöâêîôûàèùæçœãõ]{1,63}$/iu'),
00274         'PT'  => array(1 => '/^[\x{002d}0-9a-záàâãçéêíóôõú]{1,63}$/iu'),
00275         'RU'  => array(1 => '/^[\x{002d}0-9а-яё]{1,63}$/iu'),
00276         'SA'  => array(1 => '/^[\x{002d}.0-9\x{0621}-\x{063A}\x{0641}-\x{064A}\x{0660}-\x{0669}]{1,63}$/iu'),
00277         'SE'  => array(1 => '/^[\x{002d}0-9a-zäåéöü]{1,63}$/iu'),
00278         'SH'  => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'),
00279         'SJ'  => array(1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'),
00280         'TH'  => array(1 => '/^[\x{002d}0-9a-z\x{0E01}-\x{0E3A}\x{0E40}-\x{0E4D}\x{0E50}-\x{0E59}]{1,63}$/iu'),
00281         'TM'  => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$/iu'),
00282         'TW'  => 'Zend/Validate/Hostname/Cn.php',
00283         'TR'  => array(1 => '/^[\x{002d}0-9a-zğıüşöç]{1,63}$/iu'),
00284         'VE'  => array(1 => '/^[\x{002d}0-9a-záéíóúüñ]{1,63}$/iu'),
00285         'VN'  => array(1 => '/^[ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚÝàáâãèéêìíòóôõùúýĂăĐđĨĩŨũƠơƯư\x{1EA0}-\x{1EF9}]{1,63}$/iu'),
00286         'ایران' => 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'),
00287         '中国' => 'Zend/Validate/Hostname/Cn.php',
00288         '公司' => 'Zend/Validate/Hostname/Cn.php',
00289         '网络' => 'Zend/Validate/Hostname/Cn.php'
00290     );
00291 
00292     protected $_idnLength = array(
00293         'BIZ' => array(5 => 17, 11 => 15, 12 => 20),
00294         'CN'  => array(1 => 20),
00295         'COM' => array(3 => 17, 5 => 20),
00296         'HK'  => array(1 => 15),
00297         'INFO'=> array(4 => 17),
00298         'KR'  => array(1 => 17),
00299         'NET' => array(3 => 17, 5 => 20),
00300         'ORG' => array(6 => 17),
00301         'TW'  => array(1 => 20),
00302         'ایران' => array(1 => 30),
00303         '中国' => array(1 => 20),
00304         '公司' => array(1 => 20),
00305         '网络' => array(1 => 20),
00306     );
00307 
00308     protected $_options = array(
00309         'allow' => self::ALLOW_DNS,
00310         'idn'   => true,
00311         'tld'   => true,
00312         'ip'    => null
00313     );
00314 
00325     public function __construct($options = array())
00326     {
00327         if ($options instanceof Zend_Config) {
00328             $options = $options->toArray();
00329         } else if (!is_array($options)) {
00330             $options = func_get_args();
00331             $temp['allow'] = array_shift($options);
00332             if (!empty($options)) {
00333                 $temp['idn'] = array_shift($options);
00334             }
00335 
00336             if (!empty($options)) {
00337                 $temp['tld'] = array_shift($options);
00338             }
00339 
00340             if (!empty($options)) {
00341                 $temp['ip'] = array_shift($options);
00342             }
00343 
00344             $options = $temp;
00345         }
00346 
00347         $options += $this->_options;
00348         $this->setOptions($options);
00349     }
00350 
00356     public function getOptions()
00357     {
00358         return $this->_options;
00359     }
00360 
00367     public function setOptions($options)
00368     {
00369         if (array_key_exists('allow', $options)) {
00370             $this->setAllow($options['allow']);
00371         }
00372 
00373         if (array_key_exists('idn', $options)) {
00374             $this->setValidateIdn($options['idn']);
00375         }
00376 
00377         if (array_key_exists('tld', $options)) {
00378             $this->setValidateTld($options['tld']);
00379         }
00380 
00381         if (array_key_exists('ip', $options)) {
00382             $this->setIpValidator($options['ip']);
00383         }
00384 
00385         return $this;
00386     }
00387 
00393     public function getIpValidator()
00394     {
00395         return $this->_options['ip'];
00396     }
00397 
00402     public function setIpValidator(Zend_Validate_Ip $ipValidator = null)
00403     {
00404         if ($ipValidator === null) {
00405             $ipValidator = new Zend_Validate_Ip();
00406         }
00407 
00408         $this->_options['ip'] = $ipValidator;
00409         return $this;
00410     }
00411 
00417     public function getAllow()
00418     {
00419         return $this->_options['allow'];
00420     }
00421 
00428     public function setAllow($allow)
00429     {
00430         $this->_options['allow'] = $allow;
00431         return $this;
00432     }
00433 
00439     public function getValidateIdn()
00440     {
00441         return $this->_options['idn'];
00442     }
00443 
00451     public function setValidateIdn ($allowed)
00452     {
00453         $this->_options['idn'] = (bool) $allowed;
00454         return $this;
00455     }
00456 
00462     public function getValidateTld()
00463     {
00464         return $this->_options['tld'];
00465     }
00466 
00474     public function setValidateTld ($allowed)
00475     {
00476         $this->_options['tld'] = (bool) $allowed;
00477         return $this;
00478     }
00479 
00489     public function isValid($value)
00490     {
00491         if (!is_string($value)) {
00492             $this->_error(self::INVALID);
00493             return false;
00494         }
00495 
00496         $this->_setValue($value);
00497         // Check input against IP address schema
00498         if (preg_match('/^[0-9.a-e:.]*$/i', $value) &&
00499             $this->_options['ip']->setTranslator($this->getTranslator())->isValid($value)) {
00500             if (!($this->_options['allow'] & self::ALLOW_IP)) {
00501                 $this->_error(self::IP_ADDRESS_NOT_ALLOWED);
00502                 return false;
00503             } else {
00504                 return true;
00505             }
00506         }
00507 
00508         // Check input against DNS hostname schema
00509         $domainParts = explode('.', $value);
00510         if ((count($domainParts) > 1) && (strlen($value) >= 4) && (strlen($value) <= 254)) {
00511             $status = false;
00512 
00513             $origenc = iconv_get_encoding('internal_encoding');
00514             iconv_set_encoding('internal_encoding', 'UTF-8');
00515             do {
00516                 // First check TLD
00517                 $matches = array();
00518                 if (preg_match('/([^.]{2,10})$/i', end($domainParts), $matches) ||
00519                     (end($domainParts) == 'ایران') || (end($domainParts) == '中国') ||
00520                     (end($domainParts) == '公司') || (end($domainParts) == '网络')) {
00521 
00522                     reset($domainParts);
00523 
00524                     // Hostname characters are: *(label dot)(label dot label); max 254 chars
00525                     // label: id-prefix [*ldh{61} id-prefix]; max 63 chars
00526                     // id-prefix: alpha / digit
00527                     // ldh: alpha / digit / dash
00528 
00529                     // Match TLD against known list
00530                     $this->_tld = strtolower($matches[1]);
00531                     if ($this->_options['tld']) {
00532                         if (!in_array($this->_tld, $this->_validTlds)) {
00533                             $this->_error(self::UNKNOWN_TLD);
00534                             $status = false;
00535                             break;
00536                         }
00537                     }
00538 
00544                     $regexChars = array(0 => '/^[a-z0-9\x2d]{1,63}$/i');
00545                     if ($this->_options['idn'] &&  isset($this->_validIdns[strtoupper($this->_tld)])) {
00546                         if (is_string($this->_validIdns[strtoupper($this->_tld)])) {
00547                             $regexChars += include($this->_validIdns[strtoupper($this->_tld)]);
00548                         } else {
00549                             $regexChars += $this->_validIdns[strtoupper($this->_tld)];
00550                         }
00551                     }
00552 
00553                     // Check each hostname part
00554                     $check = 0;
00555                     foreach ($domainParts as $domainPart) {
00556                         // Decode Punycode domainnames to IDN
00557                         if (strpos($domainPart, 'xn--') === 0) {
00558                             $domainPart = $this->decodePunycode(substr($domainPart, 4));
00559                             if ($domainPart === false) {
00560                                 return false;
00561                             }
00562                         }
00563 
00564                         // Check dash (-) does not start, end or appear in 3rd and 4th positions
00565                         if ((strpos($domainPart, '-') === 0)
00566                             || ((strlen($domainPart) > 2) && (strpos($domainPart, '-', 2) == 2) && (strpos($domainPart, '-', 3) == 3))
00567                             || (strpos($domainPart, '-') === (strlen($domainPart) - 1))) {
00568                                 $this->_error(self::INVALID_DASH);
00569                             $status = false;
00570                             break 2;
00571                         }
00572 
00573                         // Check each domain part
00574                         $checked = false;
00575                         foreach($regexChars as $regexKey => $regexChar) {
00576                             $status = @preg_match($regexChar, $domainPart);
00577                             if ($status > 0) {
00578                                 $length = 63;
00579                                 if (array_key_exists(strtoupper($this->_tld), $this->_idnLength)
00580                                     && (array_key_exists($regexKey, $this->_idnLength[strtoupper($this->_tld)]))) {
00581                                     $length = $this->_idnLength[strtoupper($this->_tld)];
00582                                 }
00583 
00584                                 if (iconv_strlen($domainPart, 'UTF-8') > $length) {
00585                                     $this->_error(self::INVALID_HOSTNAME);
00586                                 } else {
00587                                     $checked = true;
00588                                     break;
00589                                 }
00590                             }
00591                         }
00592 
00593                         if ($checked) {
00594                             ++$check;
00595                         }
00596                     }
00597 
00598                     // If one of the labels doesn't match, the hostname is invalid
00599                     if ($check !== count($domainParts)) {
00600                         $this->_error(self::INVALID_HOSTNAME_SCHEMA);
00601                         $status = false;
00602                     }
00603                 } else {
00604                     // Hostname not long enough
00605                     $this->_error(self::UNDECIPHERABLE_TLD);
00606                     $status = false;
00607                 }
00608             } while (false);
00609 
00610             iconv_set_encoding('internal_encoding', $origenc);
00611             // If the input passes as an Internet domain name, and domain names are allowed, then the hostname
00612             // passes validation
00613             if ($status && ($this->_options['allow'] & self::ALLOW_DNS)) {
00614                 return true;
00615             }
00616         } else if ($this->_options['allow'] & self::ALLOW_DNS) {
00617             $this->_error(self::INVALID_HOSTNAME);
00618         }
00619 
00620         // Check input against local network name schema; last chance to pass validation
00621         $regexLocal = '/^(([a-zA-Z0-9\x2d]{1,63}\x2e)*[a-zA-Z0-9\x2d]{1,63}){1,254}$/';
00622         $status = @preg_match($regexLocal, $value);
00623 
00624         // If the input passes as a local network name, and local network names are allowed, then the
00625         // hostname passes validation
00626         $allowLocal = $this->_options['allow'] & self::ALLOW_LOCAL;
00627         if ($status && $allowLocal) {
00628             return true;
00629         }
00630 
00631         // If the input does not pass as a local network name, add a message
00632         if (!$status) {
00633             $this->_error(self::INVALID_LOCAL_NAME);
00634         }
00635 
00636         // If local network names are not allowed, add a message
00637         if ($status && !$allowLocal) {
00638             $this->_error(self::LOCAL_NAME_NOT_ALLOWED);
00639         }
00640 
00641         return false;
00642     }
00643 
00651     protected function decodePunycode($encoded)
00652     {
00653         $found = preg_match('/([^a-z0-9\x2d]{1,10})$/i', $encoded);
00654         if (empty($encoded) || ($found > 0)) {
00655             // no punycode encoded string, return as is
00656             $this->_error(self::CANNOT_DECODE_PUNYCODE);
00657             return false;
00658         }
00659 
00660         $separator = strrpos($encoded, '-');
00661         if ($separator > 0) {
00662             for ($x = 0; $x < $separator; ++$x) {
00663                 // prepare decoding matrix
00664                 $decoded[] = ord($encoded[$x]);
00665             }
00666         } else {
00667             $this->_error(self::CANNOT_DECODE_PUNYCODE);
00668             return false;
00669         }
00670 
00671         $lengthd = count($decoded);
00672         $lengthe = strlen($encoded);
00673 
00674         // decoding
00675         $init  = true;
00676         $base  = 72;
00677         $index = 0;
00678         $char  = 0x80;
00679 
00680         for ($indexe = ($separator) ? ($separator + 1) : 0; $indexe < $lengthe; ++$lengthd) {
00681             for ($old_index = $index, $pos = 1, $key = 36; 1 ; $key += 36) {
00682                 $hex   = ord($encoded[$indexe++]);
00683                 $digit = ($hex - 48 < 10) ? $hex - 22
00684                        : (($hex - 65 < 26) ? $hex - 65
00685                        : (($hex - 97 < 26) ? $hex - 97
00686                        : 36));
00687 
00688                 $index += $digit * $pos;
00689                 $tag    = ($key <= $base) ? 1 : (($key >= $base + 26) ? 26 : ($key - $base));
00690                 if ($digit < $tag) {
00691                     break;
00692                 }
00693 
00694                 $pos = (int) ($pos * (36 - $tag));
00695             }
00696 
00697             $delta   = intval($init ? (($index - $old_index) / 700) : (($index - $old_index) / 2));
00698             $delta  += intval($delta / ($lengthd + 1));
00699             for ($key = 0; $delta > 910 / 2; $key += 36) {
00700                 $delta = intval($delta / 35);
00701             }
00702 
00703             $base   = intval($key + 36 * $delta / ($delta + 38));
00704             $init   = false;
00705             $char  += (int) ($index / ($lengthd + 1));
00706             $index %= ($lengthd + 1);
00707             if ($lengthd > 0) {
00708                 for ($i = $lengthd; $i > $index; $i--) {
00709                     $decoded[$i] = $decoded[($i - 1)];
00710                 }
00711             }
00712 
00713             $decoded[$index++] = $char;
00714         }
00715 
00716         // convert decoded ucs4 to utf8 string
00717         foreach ($decoded as $key => $value) {
00718             if ($value < 128) {
00719                 $decoded[$key] = chr($value);
00720             } elseif ($value < (1 << 11)) {
00721                 $decoded[$key]  = chr(192 + ($value >> 6));
00722                 $decoded[$key] .= chr(128 + ($value & 63));
00723             } elseif ($value < (1 << 16)) {
00724                 $decoded[$key]  = chr(224 + ($value >> 12));
00725                 $decoded[$key] .= chr(128 + (($value >> 6) & 63));
00726                 $decoded[$key] .= chr(128 + ($value & 63));
00727             } elseif ($value < (1 << 21)) {
00728                 $decoded[$key]  = chr(240 + ($value >> 18));
00729                 $decoded[$key] .= chr(128 + (($value >> 12) & 63));
00730                 $decoded[$key] .= chr(128 + (($value >> 6) & 63));
00731                 $decoded[$key] .= chr(128 + ($value & 63));
00732             } else {
00733                 $this->_error(self::CANNOT_DECODE_PUNYCODE);
00734                 return false;
00735             }
00736         }
00737 
00738         return implode($decoded);
00739     }
00740 }
 All Data Structures Namespaces Files Functions Variables Enumerations