[ Index ] |
PHP Cross Reference of vtigercrm-6.1.0 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Zend Framework 4 * 5 * LICENSE 6 * 7 * This source file is subject to the new BSD license that is bundled 8 * with this package in the file LICENSE.txt. 9 * It is also available through the world-wide-web at this URL: 10 * http://framework.zend.com/license/new-bsd 11 * If you did not receive a copy of the license and are unable to 12 * obtain it through the world-wide-web, please send an email 13 * to [email protected] so we can send you a copy immediately. 14 * 15 * @category Zend 16 * @package Zend_Validate 17 * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) 18 * @license http://framework.zend.com/license/new-bsd New BSD License 19 * @version $Id: Hostname.php 24631 2012-02-24 17:43:08Z adamlundrigan $ 20 */ 21 22 /** 23 * @see Zend_Validate_Abstract 24 */ 25 require_once 'Zend/Validate/Abstract.php'; 26 27 /** 28 * @see Zend_Validate_Ip 29 */ 30 require_once 'Zend/Validate/Ip.php'; 31 32 /** 33 * Please note there are two standalone test scripts for testing IDN characters due to problems 34 * with file encoding. 35 * 36 * The first is tests/Zend/Validate/HostnameTestStandalone.php which is designed to be run on 37 * the command line. 38 * 39 * The second is tests/Zend/Validate/HostnameTestForm.php which is designed to be run via HTML 40 * to allow users to test entering UTF-8 characters in a form. 41 * 42 * @category Zend 43 * @package Zend_Validate 44 * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) 45 * @license http://framework.zend.com/license/new-bsd New BSD License 46 */ 47 class Zend_Validate_Hostname extends Zend_Validate_Abstract 48 { 49 const CANNOT_DECODE_PUNYCODE = 'hostnameCannotDecodePunycode'; 50 const INVALID = 'hostnameInvalid'; 51 const INVALID_DASH = 'hostnameDashCharacter'; 52 const INVALID_HOSTNAME = 'hostnameInvalidHostname'; 53 const INVALID_HOSTNAME_SCHEMA = 'hostnameInvalidHostnameSchema'; 54 const INVALID_LOCAL_NAME = 'hostnameInvalidLocalName'; 55 const INVALID_URI = 'hostnameInvalidUri'; 56 const IP_ADDRESS_NOT_ALLOWED = 'hostnameIpAddressNotAllowed'; 57 const LOCAL_NAME_NOT_ALLOWED = 'hostnameLocalNameNotAllowed'; 58 const UNDECIPHERABLE_TLD = 'hostnameUndecipherableTld'; 59 const UNKNOWN_TLD = 'hostnameUnknownTld'; 60 61 /** 62 * @var array 63 */ 64 protected $_messageTemplates = array( 65 self::CANNOT_DECODE_PUNYCODE => "'%value%' appears to be a DNS hostname but the given punycode notation cannot be decoded", 66 self::INVALID => "Invalid type given. String expected", 67 self::INVALID_DASH => "'%value%' appears to be a DNS hostname but contains a dash in an invalid position", 68 self::INVALID_HOSTNAME => "'%value%' does not match the expected structure for a DNS hostname", 69 self::INVALID_HOSTNAME_SCHEMA => "'%value%' appears to be a DNS hostname but cannot match against hostname schema for TLD '%tld%'", 70 self::INVALID_LOCAL_NAME => "'%value%' does not appear to be a valid local network name", 71 self::INVALID_URI => "'%value%' does not appear to be a valid URI hostname", 72 self::IP_ADDRESS_NOT_ALLOWED => "'%value%' appears to be an IP address, but IP addresses are not allowed", 73 self::LOCAL_NAME_NOT_ALLOWED => "'%value%' appears to be a local network name but local network names are not allowed", 74 self::UNDECIPHERABLE_TLD => "'%value%' appears to be a DNS hostname but cannot extract TLD part", 75 self::UNKNOWN_TLD => "'%value%' appears to be a DNS hostname but cannot match TLD against known list", 76 ); 77 78 /** 79 * @var array 80 */ 81 protected $_messageVariables = array( 82 'tld' => '_tld' 83 ); 84 85 /** 86 * Allows Internet domain names (e.g., example.com) 87 */ 88 const ALLOW_DNS = 1; 89 90 /** 91 * Allows IP addresses 92 */ 93 const ALLOW_IP = 2; 94 95 /** 96 * Allows local network names (e.g., localhost, www.localdomain) 97 */ 98 const ALLOW_LOCAL = 4; 99 100 /** 101 * Allows all types of hostnames 102 */ 103 const ALLOW_URI = 8; 104 105 /** 106 * Allows all types of hostnames 107 */ 108 const ALLOW_ALL = 15; 109 110 /** 111 * Array of valid top-level-domains 112 * 113 * @see ftp://data.iana.org/TLD/tlds-alpha-by-domain.txt List of all TLDs by domain 114 * @see http://www.iana.org/domains/root/db/ Official list of supported TLDs 115 * @var array 116 */ 117 protected $_validTlds = array( 118 'ac', 'ad', 'ae', 'aero', 'af', 'ag', 'ai', 'al', 'am', 'an', 'ao', 'aq', 'ar', 'arpa', 119 'as', 'asia', 'at', 'au', 'aw', 'ax', 'az', 'ba', 'bb', 'bd', 'be', 'bf', 'bg', 'bh', 'bi', 120 'biz', 'bj', 'bm', 'bn', 'bo', 'br', 'bs', 'bt', 'bv', 'bw', 'by', 'bz', 'ca', 'cat', 'cc', 121 'cd', 'cf', 'cg', 'ch', 'ci', 'ck', 'cl', 'cm', 'cn', 'co', 'com', 'coop', 'cr', 'cu', 122 'cv', 'cx', 'cy', 'cz', 'de', 'dj', 'dk', 'dm', 'do', 'dz', 'ec', 'edu', 'ee', 'eg', 'er', 123 'es', 'et', 'eu', 'fi', 'fj', 'fk', 'fm', 'fo', 'fr', 'ga', 'gb', 'gd', 'ge', 'gf', 'gg', 124 'gh', 'gi', 'gl', 'gm', 'gn', 'gov', 'gp', 'gq', 'gr', 'gs', 'gt', 'gu', 'gw', 'gy', 'hk', 125 'hm', 'hn', 'hr', 'ht', 'hu', 'id', 'ie', 'il', 'im', 'in', 'info', 'int', 'io', 'iq', 126 'ir', 'is', 'it', 'je', 'jm', 'jo', 'jobs', 'jp', 'ke', 'kg', 'kh', 'ki', 'km', 'kn', 'kp', 127 'kr', 'kw', 'ky', 'kz', 'la', 'lb', 'lc', 'li', 'lk', 'lr', 'ls', 'lt', 'lu', 'lv', 'ly', 128 'ma', 'mc', 'md', 'me', 'mg', 'mh', 'mil', 'mk', 'ml', 'mm', 'mn', 'mo', 'mobi', 'mp', 129 'mq', 'mr', 'ms', 'mt', 'mu', 'museum', 'mv', 'mw', 'mx', 'my', 'mz', 'na', 'name', 'nc', 130 'ne', 'net', 'nf', 'ng', 'ni', 'nl', 'no', 'np', 'nr', 'nu', 'nz', 'om', 'org', 'pa', 'pe', 131 'pf', 'pg', 'ph', 'pk', 'pl', 'pm', 'pn', 'pr', 'pro', 'ps', 'pt', 'pw', 'py', 'qa', 're', 132 'ro', 'rs', 'ru', 'rw', 'sa', 'sb', 'sc', 'sd', 'se', 'sg', 'sh', 'si', 'sj', 'sk', 'sl', 133 'sm', 'sn', 'so', 'sr', 'st', 'su', 'sv', 'sy', 'sz', 'tc', 'td', 'tel', 'tf', 'tg', 'th', 134 'tj', 'tk', 'tl', 'tm', 'tn', 'to', 'tp', 'tr', 'travel', 'tt', 'tv', 'tw', 'tz', 'ua', 135 'ug', 'uk', 'um', 'us', 'uy', 'uz', 'va', 'vc', 've', 'vg', 'vi', 'vn', 'vu', 'wf', 'ws', 136 'xxx', 'ye', 'yt', 'yu', 'za', 'zm', 'zw' 137 ); 138 139 /** 140 * @var string 141 */ 142 protected $_tld; 143 144 /** 145 * Array for valid Idns 146 * @see http://www.iana.org/domains/idn-tables/ Official list of supported IDN Chars 147 * (.AC) Ascension Island http://www.nic.ac/pdf/AC-IDN-Policy.pdf 148 * (.AR) Argentinia http://www.nic.ar/faqidn.html 149 * (.AS) American Samoa http://www.nic.as/idn/chars.cfm 150 * (.AT) Austria http://www.nic.at/en/service/technical_information/idn/charset_converter/ 151 * (.BIZ) International http://www.iana.org/domains/idn-tables/ 152 * (.BR) Brazil http://registro.br/faq/faq6.html 153 * (.BV) Bouvett Island http://www.norid.no/domeneregistrering/idn/idn_nyetegn.en.html 154 * (.CAT) Catalan http://www.iana.org/domains/idn-tables/tables/cat_ca_1.0.html 155 * (.CH) Switzerland https://nic.switch.ch/reg/ocView.action?res=EF6GW2JBPVTG67DLNIQXU234MN6SC33JNQQGI7L6#anhang1 156 * (.CL) Chile http://www.iana.org/domains/idn-tables/tables/cl_latn_1.0.html 157 * (.COM) International http://www.verisign.com/information-services/naming-services/internationalized-domain-names/index.html 158 * (.DE) Germany http://www.denic.de/en/domains/idns/liste.html 159 * (.DK) Danmark http://www.dk-hostmaster.dk/index.php?id=151 160 * (.ES) Spain https://www.nic.es/media/2008-05/1210147705287.pdf 161 * (.FI) Finland http://www.ficora.fi/en/index/palvelut/fiverkkotunnukset/aakkostenkaytto.html 162 * (.GR) Greece https://grweb.ics.forth.gr/CharacterTable1_en.jsp 163 * (.HU) Hungary http://www.domain.hu/domain/English/szabalyzat/szabalyzat.html 164 * (.INFO) International http://www.nic.info/info/idn 165 * (.IO) British Indian Ocean Territory http://www.nic.io/IO-IDN-Policy.pdf 166 * (.IR) Iran http://www.nic.ir/Allowable_Characters_dot-iran 167 * (.IS) Iceland http://www.isnic.is/domain/rules.php 168 * (.KR) Korea http://www.iana.org/domains/idn-tables/tables/kr_ko-kr_1.0.html 169 * (.LI) Liechtenstein https://nic.switch.ch/reg/ocView.action?res=EF6GW2JBPVTG67DLNIQXU234MN6SC33JNQQGI7L6#anhang1 170 * (.LT) Lithuania http://www.domreg.lt/static/doc/public/idn_symbols-en.pdf 171 * (.MD) Moldova http://www.register.md/ 172 * (.MUSEUM) International http://www.iana.org/domains/idn-tables/tables/museum_latn_1.0.html 173 * (.NET) International http://www.verisign.com/information-services/naming-services/internationalized-domain-names/index.html 174 * (.NO) Norway http://www.norid.no/domeneregistrering/idn/idn_nyetegn.en.html 175 * (.NU) Niue http://www.worldnames.net/ 176 * (.ORG) International http://www.pir.org/index.php?db=content/FAQs&tbl=FAQs_Registrant&id=2 177 * (.PE) Peru https://www.nic.pe/nuevas_politicas_faq_2.php 178 * (.PL) Poland http://www.dns.pl/IDN/allowed_character_sets.pdf 179 * (.PR) Puerto Rico http://www.nic.pr/idn_rules.asp 180 * (.PT) Portugal https://online.dns.pt/dns_2008/do?com=DS;8216320233;111;+PAGE(4000058)+K-CAT-CODIGO(C.125)+RCNT(100); 181 * (.RU) Russia http://www.iana.org/domains/idn-tables/tables/ru_ru-ru_1.0.html 182 * (.SA) Saudi Arabia http://www.iana.org/domains/idn-tables/tables/sa_ar_1.0.html 183 * (.SE) Sweden http://www.iis.se/english/IDN_campaignsite.shtml?lang=en 184 * (.SH) Saint Helena http://www.nic.sh/SH-IDN-Policy.pdf 185 * (.SJ) Svalbard and Jan Mayen http://www.norid.no/domeneregistrering/idn/idn_nyetegn.en.html 186 * (.TH) Thailand http://www.iana.org/domains/idn-tables/tables/th_th-th_1.0.html 187 * (.TM) Turkmenistan http://www.nic.tm/TM-IDN-Policy.pdf 188 * (.TR) Turkey https://www.nic.tr/index.php 189 * (.VE) Venice http://www.iana.org/domains/idn-tables/tables/ve_es_1.0.html 190 * (.VN) Vietnam http://www.vnnic.vn/english/5-6-300-2-2-04-20071115.htm#1.%20Introduction 191 * 192 * @var array 193 */ 194 protected $_validIdns = array( 195 'AC' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$/iu'), 196 'AR' => array(1 => '/^[\x{002d}0-9a-zà-ãç-êìíñ-õü]{1,63}$/iu'), 197 'AS' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźż]{1,63}$/iu'), 198 'AT' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿœšž]{1,63}$/iu'), 199 'BIZ' => 'Hostname/Biz.php', 200 'BR' => array(1 => '/^[\x{002d}0-9a-zà-ãçéíó-õúü]{1,63}$/iu'), 201 'BV' => array(1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'), 202 'CAT' => array(1 => '/^[\x{002d}0-9a-z·àç-éíïòóúü]{1,63}$/iu'), 203 'CH' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿœ]{1,63}$/iu'), 204 'CL' => array(1 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu'), 205 'CN' => 'Hostname/Cn.php', 206 'COM' => 'Zend/Validate/Hostname/Com.php', 207 'DE' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'), 208 'DK' => array(1 => '/^[\x{002d}0-9a-zäéöü]{1,63}$/iu'), 209 'ES' => array(1 => '/^[\x{002d}0-9a-zàáçèéíïñòóúü·]{1,63}$/iu'), 210 'EU' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿ]{1,63}$/iu', 211 2 => '/^[\x{002d}0-9a-zāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĺļľŀłńņňʼnŋōŏőœŕŗřśŝšťŧũūŭůűųŵŷźżž]{1,63}$/iu', 212 3 => '/^[\x{002d}0-9a-zșț]{1,63}$/iu', 213 4 => '/^[\x{002d}0-9a-zΐάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ]{1,63}$/iu', 214 5 => '/^[\x{002d}0-9a-zабвгдежзийклмнопрстуфхцчшщъыьэюя]{1,63}$/iu', 215 6 => '/^[\x{002d}0-9a-zἀ-ἇἐ-ἕἠ-ἧἰ-ἷὀ-ὅὐ-ὗὠ-ὧὰ-ώᾀ-ᾇᾐ-ᾗᾠ-ᾧᾰ-ᾴᾶᾷῂῃῄῆῇῐ-ΐῖῗῠ-ῧῲῳῴῶῷ]{1,63}$/iu'), 216 'FI' => array(1 => '/^[\x{002d}0-9a-zäåö]{1,63}$/iu'), 217 'GR' => array(1 => '/^[\x{002d}0-9a-zΆΈΉΊΌΎ-ΡΣ-ώἀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼῂῃῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲῳῴῶ-ῼ]{1,63}$/iu'), 218 'HK' => 'Zend/Validate/Hostname/Cn.php', 219 'HU' => array(1 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu'), 220 'INFO'=> array(1 => '/^[\x{002d}0-9a-zäåæéöøü]{1,63}$/iu', 221 2 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu', 222 3 => '/^[\x{002d}0-9a-záæéíðóöúýþ]{1,63}$/iu', 223 4 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu', 224 5 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu', 225 6 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu', 226 7 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu', 227 8 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu'), 228 'IO' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'), 229 'IS' => array(1 => '/^[\x{002d}0-9a-záéýúíóþæöð]{1,63}$/iu'), 230 'JP' => 'Zend/Validate/Hostname/Jp.php', 231 'KR' => array(1 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu'), 232 'LI' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿœ]{1,63}$/iu'), 233 'LT' => array(1 => '/^[\x{002d}0-9ąčęėįšųūž]{1,63}$/iu'), 234 'MD' => array(1 => '/^[\x{002d}0-9ăâîşţ]{1,63}$/iu'), 235 'MUSEUM' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćċčďđēėęěğġģħīįıķĺļľłńņňŋōőœŕŗřśşšţťŧūůűųŵŷźżžǎǐǒǔ\x{01E5}\x{01E7}\x{01E9}\x{01EF}ə\x{0292}ẁẃẅỳ]{1,63}$/iu'), 236 'NET' => 'Zend/Validate/Hostname/Com.php', 237 'NO' => array(1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'), 238 'NU' => 'Zend/Validate/Hostname/Com.php', 239 'ORG' => array(1 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu', 240 2 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu', 241 3 => '/^[\x{002d}0-9a-záäåæéëíðóöøúüýþ]{1,63}$/iu', 242 4 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu', 243 5 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu', 244 6 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu', 245 7 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu'), 246 'PE' => array(1 => '/^[\x{002d}0-9a-zñáéíóúü]{1,63}$/iu'), 247 'PL' => array(1 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu', 248 2 => '/^[\x{002d}а-ик-ш\x{0450}ѓѕјљњќџ]{1,63}$/iu', 249 3 => '/^[\x{002d}0-9a-zâîăşţ]{1,63}$/iu', 250 4 => '/^[\x{002d}0-9а-яё\x{04C2}]{1,63}$/iu', 251 5 => '/^[\x{002d}0-9a-zàáâèéêìíîòóôùúûċġħż]{1,63}$/iu', 252 6 => '/^[\x{002d}0-9a-zàäåæéêòóôöøü]{1,63}$/iu', 253 7 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu', 254 8 => '/^[\x{002d}0-9a-zàáâãçéêíòóôõúü]{1,63}$/iu', 255 9 => '/^[\x{002d}0-9a-zâîăşţ]{1,63}$/iu', 256 10=> '/^[\x{002d}0-9a-záäéíóôúýčďĺľňŕšťž]{1,63}$/iu', 257 11=> '/^[\x{002d}0-9a-zçë]{1,63}$/iu', 258 12=> '/^[\x{002d}0-9а-ик-шђјљњћџ]{1,63}$/iu', 259 13=> '/^[\x{002d}0-9a-zćčđšž]{1,63}$/iu', 260 14=> '/^[\x{002d}0-9a-zâçöûüğış]{1,63}$/iu', 261 15=> '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu', 262 16=> '/^[\x{002d}0-9a-zäõöüšž]{1,63}$/iu', 263 17=> '/^[\x{002d}0-9a-zĉĝĥĵŝŭ]{1,63}$/iu', 264 18=> '/^[\x{002d}0-9a-zâäéëîô]{1,63}$/iu', 265 19=> '/^[\x{002d}0-9a-zàáâäåæçèéêëìíîïðñòôöøùúûüýćčłńřśš]{1,63}$/iu', 266 20=> '/^[\x{002d}0-9a-zäåæõöøüšž]{1,63}$/iu', 267 21=> '/^[\x{002d}0-9a-zàáçèéìíòóùú]{1,63}$/iu', 268 22=> '/^[\x{002d}0-9a-zàáéíóöúüőű]{1,63}$/iu', 269 23=> '/^[\x{002d}0-9ΐά-ώ]{1,63}$/iu', 270 24=> '/^[\x{002d}0-9a-zàáâåæçèéêëðóôöøüþœ]{1,63}$/iu', 271 25=> '/^[\x{002d}0-9a-záäéíóöúüýčďěňřšťůž]{1,63}$/iu', 272 26=> '/^[\x{002d}0-9a-z·àçèéíïòóúü]{1,63}$/iu', 273 27=> '/^[\x{002d}0-9а-ъьюя\x{0450}\x{045D}]{1,63}$/iu', 274 28=> '/^[\x{002d}0-9а-яёіў]{1,63}$/iu', 275 29=> '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu', 276 30=> '/^[\x{002d}0-9a-záäåæéëíðóöøúüýþ]{1,63}$/iu', 277 31=> '/^[\x{002d}0-9a-zàâæçèéêëîïñôùûüÿœ]{1,63}$/iu', 278 32=> '/^[\x{002d}0-9а-щъыьэюяёєіїґ]{1,63}$/iu', 279 33=> '/^[\x{002d}0-9א-ת]{1,63}$/iu'), 280 'PR' => array(1 => '/^[\x{002d}0-9a-záéíóúñäëïüöâêîôûàèùæçœãõ]{1,63}$/iu'), 281 'PT' => array(1 => '/^[\x{002d}0-9a-záàâãçéêíóôõú]{1,63}$/iu'), 282 'RU' => array(1 => '/^[\x{002d}0-9а-яё]{1,63}$/iu'), 283 'SA' => array(1 => '/^[\x{002d}.0-9\x{0621}-\x{063A}\x{0641}-\x{064A}\x{0660}-\x{0669}]{1,63}$/iu'), 284 'SE' => array(1 => '/^[\x{002d}0-9a-zäåéöü]{1,63}$/iu'), 285 'SH' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'), 286 'SI' => array( 287 1 => '/^[\x{002d}0-9a-zà-öø-ÿ]{1,63}$/iu', 288 2 => '/^[\x{002d}0-9a-zāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĺļľŀłńņňʼnŋōŏőœŕŗřśŝšťŧũūŭůűųŵŷźżž]{1,63}$/iu', 289 3 => '/^[\x{002d}0-9a-zșț]{1,63}$/iu'), 290 'SJ' => array(1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'), 291 'TH' => array(1 => '/^[\x{002d}0-9a-z\x{0E01}-\x{0E3A}\x{0E40}-\x{0E4D}\x{0E50}-\x{0E59}]{1,63}$/iu'), 292 'TM' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$/iu'), 293 'TW' => 'Zend/Validate/Hostname/Cn.php', 294 'TR' => array(1 => '/^[\x{002d}0-9a-zğıüşöç]{1,63}$/iu'), 295 'VE' => array(1 => '/^[\x{002d}0-9a-záéíóúüñ]{1,63}$/iu'), 296 'VN' => array(1 => '/^[ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚÝàáâãèéêìíòóôõùúýĂăĐđĨĩŨũƠơƯư\x{1EA0}-\x{1EF9}]{1,63}$/iu'), 297 'ایران' => 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'), 298 '中国' => 'Zend/Validate/Hostname/Cn.php', 299 '公司' => 'Zend/Validate/Hostname/Cn.php', 300 '网络' => 'Zend/Validate/Hostname/Cn.php' 301 ); 302 303 protected $_idnLength = array( 304 'BIZ' => array(5 => 17, 11 => 15, 12 => 20), 305 'CN' => array(1 => 20), 306 'COM' => array(3 => 17, 5 => 20), 307 'HK' => array(1 => 15), 308 'INFO'=> array(4 => 17), 309 'KR' => array(1 => 17), 310 'NET' => array(3 => 17, 5 => 20), 311 'ORG' => array(6 => 17), 312 'TW' => array(1 => 20), 313 'ایران' => array(1 => 30), 314 '中国' => array(1 => 20), 315 '公司' => array(1 => 20), 316 '网络' => array(1 => 20), 317 ); 318 319 protected $_options = array( 320 'allow' => self::ALLOW_DNS, 321 'idn' => true, 322 'tld' => true, 323 'ip' => null 324 ); 325 326 /** 327 * Sets validator options 328 * 329 * @param integer $allow OPTIONAL Set what types of hostname to allow (default ALLOW_DNS) 330 * @param boolean $validateIdn OPTIONAL Set whether IDN domains are validated (default true) 331 * @param boolean $validateTld OPTIONAL Set whether the TLD element of a hostname is validated (default true) 332 * @param Zend_Validate_Ip $ipValidator OPTIONAL 333 * @return void 334 * @see http://www.iana.org/cctld/specifications-policies-cctlds-01apr02.htm Technical Specifications for ccTLDs 335 */ 336 public function __construct($options = array()) 337 { 338 if ($options instanceof Zend_Config) { 339 $options = $options->toArray(); 340 } else if (!is_array($options)) { 341 $options = func_get_args(); 342 $temp['allow'] = array_shift($options); 343 if (!empty($options)) { 344 $temp['idn'] = array_shift($options); 345 } 346 347 if (!empty($options)) { 348 $temp['tld'] = array_shift($options); 349 } 350 351 if (!empty($options)) { 352 $temp['ip'] = array_shift($options); 353 } 354 355 $options = $temp; 356 } 357 358 $options += $this->_options; 359 $this->setOptions($options); 360 } 361 362 /** 363 * Returns all set options 364 * 365 * @return array 366 */ 367 public function getOptions() 368 { 369 return $this->_options; 370 } 371 372 /** 373 * Sets the options for this validator 374 * 375 * @param array $options 376 * @return Zend_Validate_Hostname 377 */ 378 public function setOptions($options) 379 { 380 if (array_key_exists('allow', $options)) { 381 $this->setAllow($options['allow']); 382 } 383 384 if (array_key_exists('idn', $options)) { 385 $this->setValidateIdn($options['idn']); 386 } 387 388 if (array_key_exists('tld', $options)) { 389 $this->setValidateTld($options['tld']); 390 } 391 392 if (array_key_exists('ip', $options)) { 393 $this->setIpValidator($options['ip']); 394 } 395 396 return $this; 397 } 398 399 /** 400 * Returns the set ip validator 401 * 402 * @return Zend_Validate_Ip 403 */ 404 public function getIpValidator() 405 { 406 return $this->_options['ip']; 407 } 408 409 /** 410 * @param Zend_Validate_Ip $ipValidator OPTIONAL 411 * @return void; 412 */ 413 public function setIpValidator(Zend_Validate_Ip $ipValidator = null) 414 { 415 if ($ipValidator === null) { 416 $ipValidator = new Zend_Validate_Ip(); 417 } 418 419 $this->_options['ip'] = $ipValidator; 420 return $this; 421 } 422 423 /** 424 * Returns the allow option 425 * 426 * @return integer 427 */ 428 public function getAllow() 429 { 430 return $this->_options['allow']; 431 } 432 433 /** 434 * Sets the allow option 435 * 436 * @param integer $allow 437 * @return Zend_Validate_Hostname Provides a fluent interface 438 */ 439 public function setAllow($allow) 440 { 441 $this->_options['allow'] = $allow; 442 return $this; 443 } 444 445 /** 446 * Returns the set idn option 447 * 448 * @return boolean 449 */ 450 public function getValidateIdn() 451 { 452 return $this->_options['idn']; 453 } 454 455 /** 456 * Set whether IDN domains are validated 457 * 458 * This only applies when DNS hostnames are validated 459 * 460 * @param boolean $allowed Set allowed to true to validate IDNs, and false to not validate them 461 */ 462 public function setValidateIdn ($allowed) 463 { 464 $this->_options['idn'] = (bool) $allowed; 465 return $this; 466 } 467 468 /** 469 * Returns the set tld option 470 * 471 * @return boolean 472 */ 473 public function getValidateTld() 474 { 475 return $this->_options['tld']; 476 } 477 478 /** 479 * Set whether the TLD element of a hostname is validated 480 * 481 * This only applies when DNS hostnames are validated 482 * 483 * @param boolean $allowed Set allowed to true to validate TLDs, and false to not validate them 484 */ 485 public function setValidateTld ($allowed) 486 { 487 $this->_options['tld'] = (bool) $allowed; 488 return $this; 489 } 490 491 /** 492 * Defined by Zend_Validate_Interface 493 * 494 * Returns true if and only if the $value is a valid hostname with respect to the current allow option 495 * 496 * @param string $value 497 * @throws Zend_Validate_Exception if a fatal error occurs for validation process 498 * @return boolean 499 */ 500 public function isValid($value) 501 { 502 if (!is_string($value)) { 503 $this->_error(self::INVALID); 504 return false; 505 } 506 507 $this->_setValue($value); 508 // Check input against IP address schema 509 if (preg_match('/^[0-9a-f:.]*$/i', $value) && 510 $this->_options['ip']->setTranslator($this->getTranslator())->isValid($value)) { 511 if (!($this->_options['allow'] & self::ALLOW_IP)) { 512 $this->_error(self::IP_ADDRESS_NOT_ALLOWED); 513 return false; 514 } else { 515 return true; 516 } 517 } 518 519 // RFC3986 3.2.2 states: 520 // 521 // The rightmost domain label of a fully qualified domain name 522 // in DNS may be followed by a single "." and should be if it is 523 // necessary to distinguish between the complete domain name and 524 // some local domain. 525 // 526 // (see ZF-6363) 527 528 // Local hostnames are allowed to be partitial (ending '.') 529 if ($this->_options['allow'] & self::ALLOW_LOCAL) { 530 if (substr($value, -1) === '.') { 531 $value = substr($value, 0, -1); 532 if (substr($value, -1) === '.') { 533 // Empty hostnames (ending '..') are not allowed 534 $this->_error(self::INVALID_LOCAL_NAME); 535 return false; 536 } 537 } 538 } 539 540 $domainParts = explode('.', $value); 541 542 // Prevent partitial IP V4 adresses (ending '.') 543 if ((count($domainParts) == 4) && preg_match('/^[0-9.a-e:.]*$/i', $value) && 544 $this->_options['ip']->setTranslator($this->getTranslator())->isValid($value)) { 545 $this->_error(self::INVALID_LOCAL_NAME); 546 } 547 548 // Check input against DNS hostname schema 549 if ((count($domainParts) > 1) && (strlen($value) >= 4) && (strlen($value) <= 254)) { 550 $status = false; 551 552 $origenc = iconv_get_encoding('internal_encoding'); 553 iconv_set_encoding('internal_encoding', 'UTF-8'); 554 do { 555 // First check TLD 556 $matches = array(); 557 if (preg_match('/([^.]{2,10})$/i', end($domainParts), $matches) || 558 (end($domainParts) == 'ایران') || (end($domainParts) == '中国') || 559 (end($domainParts) == '公司') || (end($domainParts) == '网络')) { 560 561 reset($domainParts); 562 563 // Hostname characters are: *(label dot)(label dot label); max 254 chars 564 // label: id-prefix [*ldh{61} id-prefix]; max 63 chars 565 // id-prefix: alpha / digit 566 // ldh: alpha / digit / dash 567 568 // Match TLD against known list 569 $this->_tld = strtolower($matches[1]); 570 if ($this->_options['tld']) { 571 if (!in_array($this->_tld, $this->_validTlds)) { 572 $this->_error(self::UNKNOWN_TLD); 573 $status = false; 574 break; 575 } 576 } 577 578 /** 579 * Match against IDN hostnames 580 * Note: Keep label regex short to avoid issues with long patterns when matching IDN hostnames 581 * @see Zend_Validate_Hostname_Interface 582 */ 583 $regexChars = array(0 => '/^[a-z0-9\x2d]{1,63}$/i'); 584 if ($this->_options['idn'] && isset($this->_validIdns[strtoupper($this->_tld)])) { 585 if (is_string($this->_validIdns[strtoupper($this->_tld)])) { 586 $regexChars += include($this->_validIdns[strtoupper($this->_tld)]); 587 } else { 588 $regexChars += $this->_validIdns[strtoupper($this->_tld)]; 589 } 590 } 591 592 // Check each hostname part 593 $check = 0; 594 foreach ($domainParts as $domainPart) { 595 // Decode Punycode domainnames to IDN 596 if (strpos($domainPart, 'xn--') === 0) { 597 $domainPart = $this->decodePunycode(substr($domainPart, 4)); 598 if ($domainPart === false) { 599 return false; 600 } 601 } 602 603 // Check dash (-) does not start, end or appear in 3rd and 4th positions 604 if ((strpos($domainPart, '-') === 0) 605 || ((strlen($domainPart) > 2) && (strpos($domainPart, '-', 2) == 2) && (strpos($domainPart, '-', 3) == 3)) 606 || (strpos($domainPart, '-') === (strlen($domainPart) - 1))) { 607 $this->_error(self::INVALID_DASH); 608 $status = false; 609 break 2; 610 } 611 612 // Check each domain part 613 $checked = false; 614 foreach($regexChars as $regexKey => $regexChar) { 615 $status = @preg_match($regexChar, $domainPart); 616 if ($status > 0) { 617 $length = 63; 618 if (array_key_exists(strtoupper($this->_tld), $this->_idnLength) 619 && (array_key_exists($regexKey, $this->_idnLength[strtoupper($this->_tld)]))) { 620 $length = $this->_idnLength[strtoupper($this->_tld)]; 621 } 622 623 if (iconv_strlen($domainPart, 'UTF-8') > $length) { 624 $this->_error(self::INVALID_HOSTNAME); 625 } else { 626 $checked = true; 627 break; 628 } 629 } 630 } 631 632 if ($checked) { 633 ++$check; 634 } 635 } 636 637 // If one of the labels doesn't match, the hostname is invalid 638 if ($check !== count($domainParts)) { 639 $this->_error(self::INVALID_HOSTNAME_SCHEMA); 640 $status = false; 641 } 642 } else { 643 // Hostname not long enough 644 $this->_error(self::UNDECIPHERABLE_TLD); 645 $status = false; 646 } 647 } while (false); 648 649 iconv_set_encoding('internal_encoding', $origenc); 650 // If the input passes as an Internet domain name, and domain names are allowed, then the hostname 651 // passes validation 652 if ($status && ($this->_options['allow'] & self::ALLOW_DNS)) { 653 return true; 654 } 655 } else if ($this->_options['allow'] & self::ALLOW_DNS) { 656 $this->_error(self::INVALID_HOSTNAME); 657 } 658 659 // Check for URI Syntax (RFC3986) 660 if ($this->_options['allow'] & self::ALLOW_URI) { 661 if (preg_match("/^([a-zA-Z0-9-._~!$&\'()*+,;=]|%[[:xdigit:]]{2}){1,254}$/i", $value)) { 662 return true; 663 } else { 664 $this->_error(self::INVALID_URI); 665 } 666 } 667 668 // Check input against local network name schema; last chance to pass validation 669 $regexLocal = '/^(([a-zA-Z0-9\x2d]{1,63}\x2e)*[a-zA-Z0-9\x2d]{1,63}[\x2e]{0,1}){1,254}$/'; 670 $status = @preg_match($regexLocal, $value); 671 672 // If the input passes as a local network name, and local network names are allowed, then the 673 // hostname passes validation 674 $allowLocal = $this->_options['allow'] & self::ALLOW_LOCAL; 675 if ($status && $allowLocal) { 676 return true; 677 } 678 679 // If the input does not pass as a local network name, add a message 680 if (!$status) { 681 $this->_error(self::INVALID_LOCAL_NAME); 682 } 683 684 // If local network names are not allowed, add a message 685 if ($status && !$allowLocal) { 686 $this->_error(self::LOCAL_NAME_NOT_ALLOWED); 687 } 688 689 return false; 690 } 691 692 /** 693 * Decodes a punycode encoded string to it's original utf8 string 694 * In case of a decoding failure the original string is returned 695 * 696 * @param string $encoded Punycode encoded string to decode 697 * @return string 698 */ 699 protected function decodePunycode($encoded) 700 { 701 $found = preg_match('/([^a-z0-9\x2d]{1,10})$/i', $encoded); 702 if (empty($encoded) || ($found > 0)) { 703 // no punycode encoded string, return as is 704 $this->_error(self::CANNOT_DECODE_PUNYCODE); 705 return false; 706 } 707 708 $separator = strrpos($encoded, '-'); 709 if ($separator > 0) { 710 for ($x = 0; $x < $separator; ++$x) { 711 // prepare decoding matrix 712 $decoded[] = ord($encoded[$x]); 713 } 714 } else { 715 $this->_error(self::CANNOT_DECODE_PUNYCODE); 716 return false; 717 } 718 719 $lengthd = count($decoded); 720 $lengthe = strlen($encoded); 721 722 // decoding 723 $init = true; 724 $base = 72; 725 $index = 0; 726 $char = 0x80; 727 728 for ($indexe = ($separator) ? ($separator + 1) : 0; $indexe < $lengthe; ++$lengthd) { 729 for ($old_index = $index, $pos = 1, $key = 36; 1 ; $key += 36) { 730 $hex = ord($encoded[$indexe++]); 731 $digit = ($hex - 48 < 10) ? $hex - 22 732 : (($hex - 65 < 26) ? $hex - 65 733 : (($hex - 97 < 26) ? $hex - 97 734 : 36)); 735 736 $index += $digit * $pos; 737 $tag = ($key <= $base) ? 1 : (($key >= $base + 26) ? 26 : ($key - $base)); 738 if ($digit < $tag) { 739 break; 740 } 741 742 $pos = (int) ($pos * (36 - $tag)); 743 } 744 745 $delta = intval($init ? (($index - $old_index) / 700) : (($index - $old_index) / 2)); 746 $delta += intval($delta / ($lengthd + 1)); 747 for ($key = 0; $delta > 910 / 2; $key += 36) { 748 $delta = intval($delta / 35); 749 } 750 751 $base = intval($key + 36 * $delta / ($delta + 38)); 752 $init = false; 753 $char += (int) ($index / ($lengthd + 1)); 754 $index %= ($lengthd + 1); 755 if ($lengthd > 0) { 756 for ($i = $lengthd; $i > $index; $i--) { 757 $decoded[$i] = $decoded[($i - 1)]; 758 } 759 } 760 761 $decoded[$index++] = $char; 762 } 763 764 // convert decoded ucs4 to utf8 string 765 foreach ($decoded as $key => $value) { 766 if ($value < 128) { 767 $decoded[$key] = chr($value); 768 } elseif ($value < (1 << 11)) { 769 $decoded[$key] = chr(192 + ($value >> 6)); 770 $decoded[$key] .= chr(128 + ($value & 63)); 771 } elseif ($value < (1 << 16)) { 772 $decoded[$key] = chr(224 + ($value >> 12)); 773 $decoded[$key] .= chr(128 + (($value >> 6) & 63)); 774 $decoded[$key] .= chr(128 + ($value & 63)); 775 } elseif ($value < (1 << 21)) { 776 $decoded[$key] = chr(240 + ($value >> 18)); 777 $decoded[$key] .= chr(128 + (($value >> 12) & 63)); 778 $decoded[$key] .= chr(128 + (($value >> 6) & 63)); 779 $decoded[$key] .= chr(128 + ($value & 63)); 780 } else { 781 $this->_error(self::CANNOT_DECODE_PUNYCODE); 782 return false; 783 } 784 } 785 786 return implode($decoded); 787 } 788 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:08:37 2014 | Cross-referenced by PHPXref 0.7.1 |