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