File indexing completed on 2025-01-19 05:21:39
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Validate 0017 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0018 * @license http://framework.zend.com/license/new-bsd New BSD License 0019 * @version $Id$ 0020 */ 0021 0022 /** 0023 * @see Zend_Validate_Abstract 0024 */ 0025 // require_once 'Zend/Validate/Abstract.php'; 0026 0027 /** 0028 * @see Zend_Validate_Ip 0029 */ 0030 // require_once 'Zend/Validate/Ip.php'; 0031 0032 /** 0033 * Please note there are two standalone test scripts for testing IDN characters due to problems 0034 * with file encoding. 0035 * 0036 * The first is tests/Zend/Validate/HostnameTestStandalone.php which is designed to be run on 0037 * the command line. 0038 * 0039 * The second is tests/Zend/Validate/HostnameTestForm.php which is designed to be run via HTML 0040 * to allow users to test entering UTF-8 characters in a form. 0041 * 0042 * @category Zend 0043 * @package Zend_Validate 0044 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0045 * @license http://framework.zend.com/license/new-bsd New BSD License 0046 */ 0047 class Zend_Validate_Hostname extends Zend_Validate_Abstract 0048 { 0049 const CANNOT_DECODE_PUNYCODE = 'hostnameCannotDecodePunycode'; 0050 const INVALID = 'hostnameInvalid'; 0051 const INVALID_DASH = 'hostnameDashCharacter'; 0052 const INVALID_HOSTNAME = 'hostnameInvalidHostname'; 0053 const INVALID_HOSTNAME_SCHEMA = 'hostnameInvalidHostnameSchema'; 0054 const INVALID_LOCAL_NAME = 'hostnameInvalidLocalName'; 0055 const INVALID_URI = 'hostnameInvalidUri'; 0056 const IP_ADDRESS_NOT_ALLOWED = 'hostnameIpAddressNotAllowed'; 0057 const LOCAL_NAME_NOT_ALLOWED = 'hostnameLocalNameNotAllowed'; 0058 const UNDECIPHERABLE_TLD = 'hostnameUndecipherableTld'; 0059 const UNKNOWN_TLD = 'hostnameUnknownTld'; 0060 0061 /** 0062 * @var array 0063 */ 0064 protected $_messageTemplates = array( 0065 self::CANNOT_DECODE_PUNYCODE => "'%value%' appears to be a DNS hostname but the given punycode notation cannot be decoded", 0066 self::INVALID => "Invalid type given. String expected", 0067 self::INVALID_DASH => "'%value%' appears to be a DNS hostname but contains a dash in an invalid position", 0068 self::INVALID_HOSTNAME => "'%value%' does not match the expected structure for a DNS hostname", 0069 self::INVALID_HOSTNAME_SCHEMA => "'%value%' appears to be a DNS hostname but cannot match against hostname schema for TLD '%tld%'", 0070 self::INVALID_LOCAL_NAME => "'%value%' does not appear to be a valid local network name", 0071 self::INVALID_URI => "'%value%' does not appear to be a valid URI hostname", 0072 self::IP_ADDRESS_NOT_ALLOWED => "'%value%' appears to be an IP address, but IP addresses are not allowed", 0073 self::LOCAL_NAME_NOT_ALLOWED => "'%value%' appears to be a local network name but local network names are not allowed", 0074 self::UNDECIPHERABLE_TLD => "'%value%' appears to be a DNS hostname but cannot extract TLD part", 0075 self::UNKNOWN_TLD => "'%value%' appears to be a DNS hostname but cannot match TLD against known list", 0076 ); 0077 0078 /** 0079 * @var array 0080 */ 0081 protected $_messageVariables = array( 0082 'tld' => '_tld' 0083 ); 0084 0085 /** 0086 * Allows Internet domain names (e.g., example.com) 0087 */ 0088 const ALLOW_DNS = 1; 0089 0090 /** 0091 * Allows IP addresses 0092 */ 0093 const ALLOW_IP = 2; 0094 0095 /** 0096 * Allows local network names (e.g., localhost, www.localdomain) 0097 */ 0098 const ALLOW_LOCAL = 4; 0099 0100 /** 0101 * Allows all types of hostnames 0102 */ 0103 const ALLOW_URI = 8; 0104 0105 /** 0106 * Allows all types of hostnames 0107 */ 0108 const ALLOW_ALL = 15; 0109 0110 /** 0111 * Array of valid top-level-domains 0112 * 0113 * Version 2015091800, Last Updated Fri Sep 18 07:07:01 2015 UTC 0114 * 0115 * @see http://data.iana.org/TLD/tlds-alpha-by-domain.txt List of all TLDs by domain 0116 * @see http://www.iana.org/domains/root/db/ Official list of supported TLDs 0117 * @var array 0118 */ 0119 protected $_validTlds = array( 0120 'aaa', 0121 'abb', 0122 'abbott', 0123 'abogado', 0124 'ac', 0125 'academy', 0126 'accenture', 0127 'accountant', 0128 'accountants', 0129 'aco', 0130 'active', 0131 'actor', 0132 'ad', 0133 'ads', 0134 'adult', 0135 'ae', 0136 'aeg', 0137 'aero', 0138 'af', 0139 'afl', 0140 'ag', 0141 'agency', 0142 'ai', 0143 'aig', 0144 'airforce', 0145 'airtel', 0146 'al', 0147 'allfinanz', 0148 'alsace', 0149 'am', 0150 'amica', 0151 'amsterdam', 0152 'android', 0153 'ao', 0154 'apartments', 0155 'app', 0156 'aq', 0157 'aquarelle', 0158 'ar', 0159 'aramco', 0160 'archi', 0161 'army', 0162 'arpa', 0163 'arte', 0164 'as', 0165 'asia', 0166 'associates', 0167 'at', 0168 'attorney', 0169 'au', 0170 'auction', 0171 'audio', 0172 'auto', 0173 'autos', 0174 'aw', 0175 'ax', 0176 'axa', 0177 'az', 0178 'azure', 0179 'ba', 0180 'band', 0181 'bank', 0182 'bar', 0183 'barcelona', 0184 'barclaycard', 0185 'barclays', 0186 'bargains', 0187 'bauhaus', 0188 'bayern', 0189 'bb', 0190 'bbc', 0191 'bbva', 0192 'bcn', 0193 'bd', 0194 'be', 0195 'beer', 0196 'bentley', 0197 'berlin', 0198 'best', 0199 'bet', 0200 'bf', 0201 'bg', 0202 'bh', 0203 'bharti', 0204 'bi', 0205 'bible', 0206 'bid', 0207 'bike', 0208 'bing', 0209 'bingo', 0210 'bio', 0211 'biz', 0212 'bj', 0213 'black', 0214 'blackfriday', 0215 'bloomberg', 0216 'blue', 0217 'bm', 0218 'bms', 0219 'bmw', 0220 'bn', 0221 'bnl', 0222 'bnpparibas', 0223 'bo', 0224 'boats', 0225 'bom', 0226 'bond', 0227 'boo', 0228 'boots', 0229 'boutique', 0230 'br', 0231 'bradesco', 0232 'bridgestone', 0233 'broker', 0234 'brother', 0235 'brussels', 0236 'bs', 0237 'bt', 0238 'budapest', 0239 'build', 0240 'builders', 0241 'business', 0242 'buzz', 0243 'bv', 0244 'bw', 0245 'by', 0246 'bz', 0247 'bzh', 0248 'ca', 0249 'cab', 0250 'cafe', 0251 'cal', 0252 'camera', 0253 'camp', 0254 'cancerresearch', 0255 'canon', 0256 'capetown', 0257 'capital', 0258 'car', 0259 'caravan', 0260 'cards', 0261 'care', 0262 'career', 0263 'careers', 0264 'cars', 0265 'cartier', 0266 'casa', 0267 'cash', 0268 'casino', 0269 'cat', 0270 'catering', 0271 'cba', 0272 'cbn', 0273 'cc', 0274 'cd', 0275 'ceb', 0276 'center', 0277 'ceo', 0278 'cern', 0279 'cf', 0280 'cfa', 0281 'cfd', 0282 'cg', 0283 'ch', 0284 'chanel', 0285 'channel', 0286 'chat', 0287 'cheap', 0288 'chloe', 0289 'christmas', 0290 'chrome', 0291 'church', 0292 'ci', 0293 'cipriani', 0294 'cisco', 0295 'citic', 0296 'city', 0297 'ck', 0298 'cl', 0299 'claims', 0300 'cleaning', 0301 'click', 0302 'clinic', 0303 'clothing', 0304 'cloud', 0305 'club', 0306 'clubmed', 0307 'cm', 0308 'cn', 0309 'co', 0310 'coach', 0311 'codes', 0312 'coffee', 0313 'college', 0314 'cologne', 0315 'com', 0316 'commbank', 0317 'community', 0318 'company', 0319 'computer', 0320 'condos', 0321 'construction', 0322 'consulting', 0323 'contractors', 0324 'cooking', 0325 'cool', 0326 'coop', 0327 'corsica', 0328 'country', 0329 'coupons', 0330 'courses', 0331 'cr', 0332 'credit', 0333 'creditcard', 0334 'cricket', 0335 'crown', 0336 'crs', 0337 'cruises', 0338 'csc', 0339 'cu', 0340 'cuisinella', 0341 'cv', 0342 'cw', 0343 'cx', 0344 'cy', 0345 'cymru', 0346 'cyou', 0347 'cz', 0348 'dabur', 0349 'dad', 0350 'dance', 0351 'date', 0352 'dating', 0353 'datsun', 0354 'day', 0355 'dclk', 0356 'de', 0357 'deals', 0358 'degree', 0359 'delivery', 0360 'dell', 0361 'delta', 0362 'democrat', 0363 'dental', 0364 'dentist', 0365 'desi', 0366 'design', 0367 'dev', 0368 'diamonds', 0369 'diet', 0370 'digital', 0371 'direct', 0372 'directory', 0373 'discount', 0374 'dj', 0375 'dk', 0376 'dm', 0377 'dnp', 0378 'do', 0379 'docs', 0380 'dog', 0381 'doha', 0382 'domains', 0383 'doosan', 0384 'download', 0385 'drive', 0386 'durban', 0387 'dvag', 0388 'dz', 0389 'earth', 0390 'eat', 0391 'ec', 0392 'edu', 0393 'education', 0394 'ee', 0395 'eg', 0396 'email', 0397 'emerck', 0398 'energy', 0399 'engineer', 0400 'engineering', 0401 'enterprises', 0402 'epson', 0403 'equipment', 0404 'er', 0405 'erni', 0406 'es', 0407 'esq', 0408 'estate', 0409 'et', 0410 'eu', 0411 'eurovision', 0412 'eus', 0413 'events', 0414 'everbank', 0415 'exchange', 0416 'expert', 0417 'exposed', 0418 'express', 0419 'fage', 0420 'fail', 0421 'faith', 0422 'family', 0423 'fan', 0424 'fans', 0425 'farm', 0426 'fashion', 0427 'feedback', 0428 'fi', 0429 'film', 0430 'final', 0431 'finance', 0432 'financial', 0433 'firmdale', 0434 'fish', 0435 'fishing', 0436 'fit', 0437 'fitness', 0438 'fj', 0439 'fk', 0440 'flights', 0441 'florist', 0442 'flowers', 0443 'flsmidth', 0444 'fly', 0445 'fm', 0446 'fo', 0447 'foo', 0448 'football', 0449 'forex', 0450 'forsale', 0451 'forum', 0452 'foundation', 0453 'fr', 0454 'frl', 0455 'frogans', 0456 'fund', 0457 'furniture', 0458 'futbol', 0459 'fyi', 0460 'ga', 0461 'gal', 0462 'gallery', 0463 'game', 0464 'garden', 0465 'gb', 0466 'gbiz', 0467 'gd', 0468 'gdn', 0469 'ge', 0470 'gea', 0471 'gent', 0472 'genting', 0473 'gf', 0474 'gg', 0475 'ggee', 0476 'gh', 0477 'gi', 0478 'gift', 0479 'gifts', 0480 'gives', 0481 'giving', 0482 'gl', 0483 'glass', 0484 'gle', 0485 'global', 0486 'globo', 0487 'gm', 0488 'gmail', 0489 'gmo', 0490 'gmx', 0491 'gn', 0492 'gold', 0493 'goldpoint', 0494 'golf', 0495 'goo', 0496 'goog', 0497 'google', 0498 'gop', 0499 'gov', 0500 'gp', 0501 'gq', 0502 'gr', 0503 'graphics', 0504 'gratis', 0505 'green', 0506 'gripe', 0507 'group', 0508 'gs', 0509 'gt', 0510 'gu', 0511 'gucci', 0512 'guge', 0513 'guide', 0514 'guitars', 0515 'guru', 0516 'gw', 0517 'gy', 0518 'hamburg', 0519 'hangout', 0520 'haus', 0521 'healthcare', 0522 'help', 0523 'here', 0524 'hermes', 0525 'hiphop', 0526 'hitachi', 0527 'hiv', 0528 'hk', 0529 'hm', 0530 'hn', 0531 'hockey', 0532 'holdings', 0533 'holiday', 0534 'homedepot', 0535 'homes', 0536 'honda', 0537 'horse', 0538 'host', 0539 'hosting', 0540 'hoteles', 0541 'hotmail', 0542 'house', 0543 'how', 0544 'hr', 0545 'hsbc', 0546 'ht', 0547 'hu', 0548 'hyundai', 0549 'ibm', 0550 'icbc', 0551 'ice', 0552 'icu', 0553 'id', 0554 'ie', 0555 'ifm', 0556 'iinet', 0557 'il', 0558 'im', 0559 'immo', 0560 'immobilien', 0561 'in', 0562 'industries', 0563 'infiniti', 0564 'info', 0565 'ing', 0566 'ink', 0567 'institute', 0568 'insure', 0569 'int', 0570 'international', 0571 'investments', 0572 'io', 0573 'ipiranga', 0574 'iq', 0575 'ir', 0576 'irish', 0577 'is', 0578 'ist', 0579 'istanbul', 0580 'it', 0581 'itau', 0582 'iwc', 0583 'jaguar', 0584 'java', 0585 'jcb', 0586 'je', 0587 'jetzt', 0588 'jewelry', 0589 'jlc', 0590 'jll', 0591 'jm', 0592 'jo', 0593 'jobs', 0594 'joburg', 0595 'jp', 0596 'jprs', 0597 'juegos', 0598 'kaufen', 0599 'kddi', 0600 'ke', 0601 'kg', 0602 'kh', 0603 'ki', 0604 'kia', 0605 'kim', 0606 'kinder', 0607 'kitchen', 0608 'kiwi', 0609 'km', 0610 'kn', 0611 'koeln', 0612 'komatsu', 0613 'kp', 0614 'kr', 0615 'krd', 0616 'kred', 0617 'kw', 0618 'ky', 0619 'kyoto', 0620 'kz', 0621 'la', 0622 'lacaixa', 0623 'lancaster', 0624 'land', 0625 'landrover', 0626 'lasalle', 0627 'lat', 0628 'latrobe', 0629 'law', 0630 'lawyer', 0631 'lb', 0632 'lc', 0633 'lds', 0634 'lease', 0635 'leclerc', 0636 'legal', 0637 'lexus', 0638 'lgbt', 0639 'li', 0640 'liaison', 0641 'lidl', 0642 'life', 0643 'lighting', 0644 'limited', 0645 'limo', 0646 'linde', 0647 'link', 0648 'live', 0649 'lixil', 0650 'lk', 0651 'loan', 0652 'loans', 0653 'lol', 0654 'london', 0655 'lotte', 0656 'lotto', 0657 'love', 0658 'lr', 0659 'ls', 0660 'lt', 0661 'ltd', 0662 'ltda', 0663 'lu', 0664 'lupin', 0665 'luxe', 0666 'luxury', 0667 'lv', 0668 'ly', 0669 'ma', 0670 'madrid', 0671 'maif', 0672 'maison', 0673 'man', 0674 'management', 0675 'mango', 0676 'market', 0677 'marketing', 0678 'markets', 0679 'marriott', 0680 'mba', 0681 'mc', 0682 'md', 0683 'me', 0684 'media', 0685 'meet', 0686 'melbourne', 0687 'meme', 0688 'memorial', 0689 'men', 0690 'menu', 0691 'mg', 0692 'mh', 0693 'miami', 0694 'microsoft', 0695 'mil', 0696 'mini', 0697 'mk', 0698 'ml', 0699 'mm', 0700 'mma', 0701 'mn', 0702 'mo', 0703 'mobi', 0704 'moda', 0705 'moe', 0706 'moi', 0707 'mom', 0708 'monash', 0709 'money', 0710 'montblanc', 0711 'mormon', 0712 'mortgage', 0713 'moscow', 0714 'motorcycles', 0715 'mov', 0716 'movie', 0717 'movistar', 0718 'mp', 0719 'mq', 0720 'mr', 0721 'ms', 0722 'mt', 0723 'mtn', 0724 'mtpc', 0725 'mtr', 0726 'mu', 0727 'museum', 0728 'mutuelle', 0729 'mv', 0730 'mw', 0731 'mx', 0732 'my', 0733 'mz', 0734 'na', 0735 'nadex', 0736 'nagoya', 0737 'name', 0738 'navy', 0739 'nc', 0740 'ne', 0741 'nec', 0742 'net', 0743 'netbank', 0744 'network', 0745 'neustar', 0746 'new', 0747 'news', 0748 'nexus', 0749 'nf', 0750 'ng', 0751 'ngo', 0752 'nhk', 0753 'ni', 0754 'nico', 0755 'ninja', 0756 'nissan', 0757 'nl', 0758 'no', 0759 'nokia', 0760 'np', 0761 'nr', 0762 'nra', 0763 'nrw', 0764 'ntt', 0765 'nu', 0766 'nyc', 0767 'nz', 0768 'obi', 0769 'office', 0770 'okinawa', 0771 'om', 0772 'omega', 0773 'one', 0774 'ong', 0775 'onl', 0776 'online', 0777 'ooo', 0778 'oracle', 0779 'orange', 0780 'org', 0781 'organic', 0782 'osaka', 0783 'otsuka', 0784 'ovh', 0785 'pa', 0786 'page', 0787 'panerai', 0788 'paris', 0789 'partners', 0790 'parts', 0791 'party', 0792 'pe', 0793 'pet', 0794 'pf', 0795 'pg', 0796 'ph', 0797 'pharmacy', 0798 'philips', 0799 'photo', 0800 'photography', 0801 'photos', 0802 'physio', 0803 'piaget', 0804 'pics', 0805 'pictet', 0806 'pictures', 0807 'pink', 0808 'pizza', 0809 'pk', 0810 'pl', 0811 'place', 0812 'play', 0813 'plumbing', 0814 'plus', 0815 'pm', 0816 'pn', 0817 'pohl', 0818 'poker', 0819 'porn', 0820 'post', 0821 'pr', 0822 'praxi', 0823 'press', 0824 'pro', 0825 'prod', 0826 'productions', 0827 'prof', 0828 'properties', 0829 'property', 0830 'protection', 0831 'ps', 0832 'pt', 0833 'pub', 0834 'pw', 0835 'py', 0836 'qa', 0837 'qpon', 0838 'quebec', 0839 'racing', 0840 're', 0841 'realtor', 0842 'realty', 0843 'recipes', 0844 'red', 0845 'redstone', 0846 'rehab', 0847 'reise', 0848 'reisen', 0849 'reit', 0850 'ren', 0851 'rent', 0852 'rentals', 0853 'repair', 0854 'report', 0855 'republican', 0856 'rest', 0857 'restaurant', 0858 'review', 0859 'reviews', 0860 'rich', 0861 'ricoh', 0862 'rio', 0863 'rip', 0864 'ro', 0865 'rocks', 0866 'rodeo', 0867 'rs', 0868 'rsvp', 0869 'ru', 0870 'ruhr', 0871 'run', 0872 'rw', 0873 'rwe', 0874 'ryukyu', 0875 'sa', 0876 'saarland', 0877 'sakura', 0878 'sale', 0879 'samsung', 0880 'sandvik', 0881 'sandvikcoromant', 0882 'sanofi', 0883 'sap', 0884 'sarl', 0885 'saxo', 0886 'sb', 0887 'sc', 0888 'sca', 0889 'scb', 0890 'schmidt', 0891 'scholarships', 0892 'school', 0893 'schule', 0894 'schwarz', 0895 'science', 0896 'scor', 0897 'scot', 0898 'sd', 0899 'se', 0900 'seat', 0901 'security', 0902 'seek', 0903 'sener', 0904 'services', 0905 'seven', 0906 'sew', 0907 'sex', 0908 'sexy', 0909 'sg', 0910 'sh', 0911 'shiksha', 0912 'shoes', 0913 'show', 0914 'shriram', 0915 'si', 0916 'singles', 0917 'site', 0918 'sj', 0919 'sk', 0920 'ski', 0921 'sky', 0922 'skype', 0923 'sl', 0924 'sm', 0925 'sn', 0926 'sncf', 0927 'so', 0928 'soccer', 0929 'social', 0930 'software', 0931 'sohu', 0932 'solar', 0933 'solutions', 0934 'sony', 0935 'soy', 0936 'space', 0937 'spiegel', 0938 'spreadbetting', 0939 'sr', 0940 'srl', 0941 'st', 0942 'stada', 0943 'starhub', 0944 'statoil', 0945 'stc', 0946 'stcgroup', 0947 'stockholm', 0948 'studio', 0949 'study', 0950 'style', 0951 'su', 0952 'sucks', 0953 'supplies', 0954 'supply', 0955 'support', 0956 'surf', 0957 'surgery', 0958 'suzuki', 0959 'sv', 0960 'swatch', 0961 'swiss', 0962 'sx', 0963 'sy', 0964 'sydney', 0965 'systems', 0966 'sz', 0967 'taipei', 0968 'tatamotors', 0969 'tatar', 0970 'tattoo', 0971 'tax', 0972 'taxi', 0973 'tc', 0974 'td', 0975 'team', 0976 'tech', 0977 'technology', 0978 'tel', 0979 'telefonica', 0980 'temasek', 0981 'tennis', 0982 'tf', 0983 'tg', 0984 'th', 0985 'thd', 0986 'theater', 0987 'theatre', 0988 'tickets', 0989 'tienda', 0990 'tips', 0991 'tires', 0992 'tirol', 0993 'tj', 0994 'tk', 0995 'tl', 0996 'tm', 0997 'tn', 0998 'to', 0999 'today', 1000 'tokyo', 1001 'tools', 1002 'top', 1003 'toray', 1004 'toshiba', 1005 'tours', 1006 'town', 1007 'toyota', 1008 'toys', 1009 'tr', 1010 'trade', 1011 'trading', 1012 'training', 1013 'travel', 1014 'trust', 1015 'tt', 1016 'tui', 1017 'tv', 1018 'tw', 1019 'tz', 1020 'ua', 1021 'ubs', 1022 'ug', 1023 'uk', 1024 'university', 1025 'uno', 1026 'uol', 1027 'us', 1028 'uy', 1029 'uz', 1030 'va', 1031 'vacations', 1032 'vc', 1033 've', 1034 'vegas', 1035 'ventures', 1036 'versicherung', 1037 'vet', 1038 'vg', 1039 'vi', 1040 'viajes', 1041 'video', 1042 'villas', 1043 'vin', 1044 'virgin', 1045 'vision', 1046 'vista', 1047 'vistaprint', 1048 'viva', 1049 'vlaanderen', 1050 'vn', 1051 'vodka', 1052 'vote', 1053 'voting', 1054 'voto', 1055 'voyage', 1056 'vu', 1057 'wales', 1058 'walter', 1059 'wang', 1060 'watch', 1061 'webcam', 1062 'website', 1063 'wed', 1064 'wedding', 1065 'weir', 1066 'wf', 1067 'whoswho', 1068 'wien', 1069 'wiki', 1070 'williamhill', 1071 'win', 1072 'windows', 1073 'wine', 1074 'wme', 1075 'work', 1076 'works', 1077 'world', 1078 'ws', 1079 'wtc', 1080 'wtf', 1081 'xbox', 1082 'xerox', 1083 'xin', 1084 'xn--11b4c3d', 1085 'xn--1qqw23a', 1086 'xn--30rr7y', 1087 'xn--3bst00m', 1088 'xn--3ds443g', 1089 'xn--3e0b707e', 1090 'xn--3pxu8k', 1091 'xn--42c2d9a', 1092 'xn--45brj9c', 1093 'xn--45q11c', 1094 'xn--4gbrim', 1095 'xn--55qw42g', 1096 'xn--55qx5d', 1097 'xn--6frz82g', 1098 'xn--6qq986b3xl', 1099 'xn--80adxhks', 1100 'xn--80ao21a', 1101 'xn--80asehdb', 1102 'xn--80aswg', 1103 'xn--90a3ac', 1104 'xn--90ais', 1105 'xn--9dbq2a', 1106 'xn--9et52u', 1107 'xn--b4w605ferd', 1108 'xn--c1avg', 1109 'xn--c2br7g', 1110 'xn--cg4bki', 1111 'xn--clchc0ea0b2g2a9gcd', 1112 'xn--czr694b', 1113 'xn--czrs0t', 1114 'xn--czru2d', 1115 'xn--d1acj3b', 1116 'xn--d1alf', 1117 'xn--efvy88h', 1118 'xn--estv75g', 1119 'xn--fhbei', 1120 'xn--fiq228c5hs', 1121 'xn--fiq64b', 1122 'xn--fiqs8s', 1123 'xn--fiqz9s', 1124 'xn--fjq720a', 1125 'xn--flw351e', 1126 'xn--fpcrj9c3d', 1127 'xn--fzc2c9e2c', 1128 'xn--gecrj9c', 1129 'xn--h2brj9c', 1130 'xn--hxt814e', 1131 'xn--i1b6b1a6a2e', 1132 'xn--imr513n', 1133 'xn--io0a7i', 1134 'xn--j1aef', 1135 'xn--j1amh', 1136 'xn--j6w193g', 1137 'xn--kcrx77d1x4a', 1138 'xn--kprw13d', 1139 'xn--kpry57d', 1140 'xn--kput3i', 1141 'xn--l1acc', 1142 'xn--lgbbat1ad8j', 1143 'xn--mgb9awbf', 1144 'xn--mgba3a3ejt', 1145 'xn--mgba3a4f16a', 1146 'xn--mgbaam7a8h', 1147 'xn--mgbab2bd', 1148 'xn--mgbayh7gpa', 1149 'xn--mgbbh1a71e', 1150 'xn--mgbc0a9azcg', 1151 'xn--mgberp4a5d4ar', 1152 'xn--mgbpl2fh', 1153 'xn--mgbx4cd0ab', 1154 'xn--mk1bu44c', 1155 'xn--mxtq1m', 1156 'xn--ngbc5azd', 1157 'xn--node', 1158 'xn--nqv7f', 1159 'xn--nqv7fs00ema', 1160 'xn--nyqy26a', 1161 'xn--o3cw4h', 1162 'xn--ogbpf8fl', 1163 'xn--p1acf', 1164 'xn--p1ai', 1165 'xn--pgbs0dh', 1166 'xn--pssy2u', 1167 'xn--q9jyb4c', 1168 'xn--qcka1pmc', 1169 'xn--rhqv96g', 1170 'xn--s9brj9c', 1171 'xn--ses554g', 1172 'xn--t60b56a', 1173 'xn--tckwe', 1174 'xn--unup4y', 1175 'xn--vermgensberater-ctb', 1176 'xn--vermgensberatung-pwb', 1177 'xn--vhquv', 1178 'xn--vuq861b', 1179 'xn--wgbh1c', 1180 'xn--wgbl6a', 1181 'xn--xhq521b', 1182 'xn--xkc2al3hye2a', 1183 'xn--xkc2dl3a5ee0h', 1184 'xn--y9a3aq', 1185 'xn--yfro4i67o', 1186 'xn--ygbi2ammx', 1187 'xn--zfr164b', 1188 'xperia', 1189 'xxx', 1190 'xyz', 1191 'yachts', 1192 'yamaxun', 1193 'yandex', 1194 'ye', 1195 'yodobashi', 1196 'yoga', 1197 'yokohama', 1198 'youtube', 1199 'yt', 1200 'za', 1201 'zara', 1202 'zip', 1203 'zm', 1204 'zone', 1205 'zuerich', 1206 'zw', 1207 '测试', 1208 'परीक्षा', 1209 '佛山', 1210 '集团', 1211 '在线', 1212 '한국', 1213 'ভারত', 1214 '八卦', 1215 'موقع', 1216 'বাংলা', 1217 '公益', 1218 '公司', 1219 '移动', 1220 '我爱你', 1221 'москва', 1222 'испытание', 1223 'қаз', 1224 'онлайн', 1225 'сайт', 1226 'срб', 1227 'бел', 1228 '테스트', 1229 'орг', 1230 '삼성', 1231 'சிங்கப்பூர்', 1232 '商标', 1233 '商城', 1234 'дети', 1235 'мкд', 1236 'טעסט', 1237 '中文网', 1238 '中信', 1239 '中国', 1240 '中國', 1241 '谷歌', 1242 'భారత్', 1243 'ලංකා', 1244 '測試', 1245 'ભારત', 1246 'भारत', 1247 'آزمایشی', 1248 'பரிட்சை', 1249 'संगठन', 1250 '网络', 1251 'укр', 1252 '香港', 1253 'δοκιμή', 1254 'إختبار', 1255 '台湾', 1256 '台灣', 1257 '手机', 1258 'мон', 1259 'الجزائر', 1260 'عمان', 1261 'ایران', 1262 'امارات', 1263 'بازار', 1264 'پاکستان', 1265 'الاردن', 1266 'بھارت', 1267 'المغرب', 1268 'السعودية', 1269 'سودان', 1270 'عراق', 1271 'مليسيا', 1272 'شبكة', 1273 'გე', 1274 '机构', 1275 '组织机构', 1276 'ไทย', 1277 'سورية', 1278 'рус', 1279 'рф', 1280 'تونس', 1281 'みんな', 1282 'グーグル', 1283 '世界', 1284 'ਭਾਰਤ', 1285 '网址', 1286 '游戏', 1287 'vermögensberater', 1288 'vermögensberatung', 1289 '企业', 1290 'مصر', 1291 'قطر', 1292 '广东', 1293 'இலங்கை', 1294 'இந்தியா', 1295 'հայ', 1296 '新加坡', 1297 'فلسطين', 1298 'テスト', 1299 '政务', 1300 ); 1301 1302 /** 1303 * @var string 1304 */ 1305 protected $_tld; 1306 1307 /** 1308 * Array for valid Idns 1309 * @see http://www.iana.org/domains/idn-tables/ Official list of supported IDN Chars 1310 * (.AC) Ascension Island http://www.nic.ac/pdf/AC-IDN-Policy.pdf 1311 * (.AR) Argentinia http://www.nic.ar/faqidn.html 1312 * (.AS) American Samoa http://www.nic.as/idn/chars.cfm 1313 * (.AT) Austria http://www.nic.at/en/service/technical_information/idn/charset_converter/ 1314 * (.BIZ) International http://www.iana.org/domains/idn-tables/ 1315 * (.BR) Brazil http://registro.br/faq/faq6.html 1316 * (.BV) Bouvett Island http://www.norid.no/domeneregistrering/idn/idn_nyetegn.en.html 1317 * (.CA) Canada http://www.iana.org/domains/idn-tables/tables/ca_fr_1.0.html 1318 * (.CAT) Catalan http://www.iana.org/domains/idn-tables/tables/cat_ca_1.0.html 1319 * (.CH) Switzerland https://nic.switch.ch/reg/ocView.action?res=EF6GW2JBPVTG67DLNIQXU234MN6SC33JNQQGI7L6#anhang1 1320 * (.CL) Chile http://www.iana.org/domains/idn-tables/tables/cl_latn_1.0.html 1321 * (.COM) International http://www.verisign.com/information-services/naming-services/internationalized-domain-names/index.html 1322 * (.DE) Germany http://www.denic.de/en/domains/idns/liste.html 1323 * (.DK) Danmark http://www.dk-hostmaster.dk/index.php?id=151 1324 * (.ES) Spain https://www.nic.es/media/2008-05/1210147705287.pdf 1325 * (.FI) Finland http://www.ficora.fi/en/index/palvelut/fiverkkotunnukset/aakkostenkaytto.html 1326 * (.GR) Greece https://grweb.ics.forth.gr/CharacterTable1_en.jsp 1327 * (.HU) Hungary http://www.domain.hu/domain/English/szabalyzat/szabalyzat.html 1328 * (.INFO) International http://www.nic.info/info/idn 1329 * (.IO) British Indian Ocean Territory http://www.nic.io/IO-IDN-Policy.pdf 1330 * (.IR) Iran http://www.nic.ir/Allowable_Characters_dot-iran 1331 * (.IS) Iceland http://www.isnic.is/domain/rules.php 1332 * (.KR) Korea http://www.iana.org/domains/idn-tables/tables/kr_ko-kr_1.0.html 1333 * (.LI) Liechtenstein https://nic.switch.ch/reg/ocView.action?res=EF6GW2JBPVTG67DLNIQXU234MN6SC33JNQQGI7L6#anhang1 1334 * (.LT) Lithuania http://www.domreg.lt/static/doc/public/idn_symbols-en.pdf 1335 * (.MD) Moldova http://www.register.md/ 1336 * (.MUSEUM) International http://www.iana.org/domains/idn-tables/tables/museum_latn_1.0.html 1337 * (.NET) International http://www.verisign.com/information-services/naming-services/internationalized-domain-names/index.html 1338 * (.NO) Norway http://www.norid.no/domeneregistrering/idn/idn_nyetegn.en.html 1339 * (.NU) Niue http://www.worldnames.net/ 1340 * (.ORG) International http://www.pir.org/index.php?db=content/FAQs&tbl=FAQs_Registrant&id=2 1341 * (.PE) Peru https://www.nic.pe/nuevas_politicas_faq_2.php 1342 * (.PL) Poland http://www.dns.pl/IDN/allowed_character_sets.pdf 1343 * (.PR) Puerto Rico http://www.nic.pr/idn_rules.asp 1344 * (.PT) Portugal https://online.dns.pt/dns_2008/do?com=DS;8216320233;111;+PAGE(4000058)+K-CAT-CODIGO(C.125)+RCNT(100); 1345 * (.RU) Russia http://www.iana.org/domains/idn-tables/tables/ru_ru-ru_1.0.html 1346 * (.RS) Serbia http://www.iana.org/domains/idn-tables/tables/rs_sr-rs_1.0.pdf 1347 * (.SA) Saudi Arabia http://www.iana.org/domains/idn-tables/tables/sa_ar_1.0.html 1348 * (.SE) Sweden http://www.iis.se/english/IDN_campaignsite.shtml?lang=en 1349 * (.SH) Saint Helena http://www.nic.sh/SH-IDN-Policy.pdf 1350 * (.SJ) Svalbard and Jan Mayen http://www.norid.no/domeneregistrering/idn/idn_nyetegn.en.html 1351 * (.TH) Thailand http://www.iana.org/domains/idn-tables/tables/th_th-th_1.0.html 1352 * (.TM) Turkmenistan http://www.nic.tm/TM-IDN-Policy.pdf 1353 * (.TR) Turkey https://www.nic.tr/index.php 1354 * (.UA) Ukraine http://www.iana.org/domains/idn-tables/tables/ua_cyrl_1.2.html 1355 * (.VE) Venice http://www.iana.org/domains/idn-tables/tables/ve_es_1.0.html 1356 * (.VN) Vietnam http://www.vnnic.vn/english/5-6-300-2-2-04-20071115.htm#1.%20Introduction 1357 * 1358 * @var array 1359 */ 1360 protected $_validIdns = array( 1361 'AC' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$/iu'), 1362 'AR' => array(1 => '/^[\x{002d}0-9a-zà-ãç-êìíñ-õü]{1,63}$/iu'), 1363 'AS' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźż]{1,63}$/iu'), 1364 'AT' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿœšž]{1,63}$/iu'), 1365 'BIZ' => 'Hostname/Biz.php', 1366 'BR' => array(1 => '/^[\x{002d}0-9a-zà-ãçéíó-õúü]{1,63}$/iu'), 1367 'BV' => array(1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'), 1368 'CA' => array(1 => '/^[\x{002d}0-9a-zàâæçéèêëîïôœùûüÿ\x{00E0}\x{00E2}\x{00E7}\x{00E8}\x{00E9}\x{00EA}\x{00EB}\x{00EE}\x{00EF}\x{00F4}\x{00F9}\x{00FB}\x{00FC}\x{00E6}\x{0153}\x{00FF}]{1,63}$/iu'), 1369 'CAT' => array(1 => '/^[\x{002d}0-9a-z·àç-éíïòóúü]{1,63}$/iu'), 1370 'CH' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿœ]{1,63}$/iu'), 1371 'CL' => array(1 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu'), 1372 'CN' => 'Hostname/Cn.php', 1373 'COM' => 'Hostname/Com.php', 1374 'DE' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťßţŧŭůűũųūŵŷźžż]{1,63}$/iu'), 1375 'DK' => array(1 => '/^[\x{002d}0-9a-zäéöüæøå]{1,63}$/iu'), 1376 'ES' => array(1 => '/^[\x{002d}0-9a-zàáçèéíïñòóúü·]{1,63}$/iu'), 1377 'EU' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿ]{1,63}$/iu', 1378 2 => '/^[\x{002d}0-9a-zāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĺļľŀłńņňʼnŋōŏőœŕŗřśŝšťŧũūŭůűųŵŷźżž]{1,63}$/iu', 1379 3 => '/^[\x{002d}0-9a-zșț]{1,63}$/iu', 1380 4 => '/^[\x{002d}0-9a-zΐάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ]{1,63}$/iu', 1381 5 => '/^[\x{002d}0-9a-zабвгдежзийклмнопрстуфхцчшщъыьэюя]{1,63}$/iu', 1382 6 => '/^[\x{002d}0-9a-zἀ-ἇἐ-ἕἠ-ἧἰ-ἷὀ-ὅὐ-ὗὠ-ὧὰ-ὼώᾀ-ᾇᾐ-ᾗᾠ-ᾧᾰ-ᾴᾶᾷῂῃῄῆῇῐ-ῒΐῖῗῠ-ῧῲῳῴῶῷ]{1,63}$/iu'), 1383 'FI' => array(1 => '/^[\x{002d}0-9a-zäåö]{1,63}$/iu'), 1384 'GR' => array(1 => '/^[\x{002d}0-9a-zΆΈΉΊΌΎ-ΡΣ-ώἀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼῂῃῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲῳῴῶ-ῼ]{1,63}$/iu'), 1385 'HK' => 'Hostname/Cn.php', 1386 'HU' => array(1 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu'), 1387 'IL' => array(1 => '/^[\x{002d}0-9\x{05D0}-\x{05EA}]{1,63}$/iu', 1388 2 => '/^[\x{002d}0-9a-z]{1,63}$/i'), 1389 'INFO'=> array(1 => '/^[\x{002d}0-9a-zäåæéöøü]{1,63}$/iu', 1390 2 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu', 1391 3 => '/^[\x{002d}0-9a-záæéíðóöúýþ]{1,63}$/iu', 1392 4 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu', 1393 5 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu', 1394 6 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu', 1395 7 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu', 1396 8 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu'), 1397 'IO' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'), 1398 'IS' => array(1 => '/^[\x{002d}0-9a-záéýúíóþæöð]{1,63}$/iu'), 1399 'IT' => array(1 => '/^[\x{002d}0-9a-zàâäèéêëìîïòôöùûüæœçÿß-]{1,63}$/iu'), 1400 'JP' => 'Hostname/Jp.php', 1401 'KR' => array(1 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu'), 1402 'LI' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿœ]{1,63}$/iu'), 1403 'LT' => array(1 => '/^[\x{002d}0-9ąčęėįšųūž]{1,63}$/iu'), 1404 'MD' => array(1 => '/^[\x{002d}0-9ăâîşţ]{1,63}$/iu'), 1405 'MUSEUM' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćċčďđēėęěğġģħīįıķĺļľłńņňŋōőœŕŗřśşšţťŧūůűųŵŷźżžǎǐǒǔ\x{01E5}\x{01E7}\x{01E9}\x{01EF}ə\x{0292}ẁẃẅỳ]{1,63}$/iu'), 1406 'NET' => 'Hostname/Com.php', 1407 'NO' => array(1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'), 1408 'NU' => 'Hostname/Com.php', 1409 'ORG' => array(1 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu', 1410 2 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu', 1411 3 => '/^[\x{002d}0-9a-záäåæéëíðóöøúüýþ]{1,63}$/iu', 1412 4 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu', 1413 5 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu', 1414 6 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu', 1415 7 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu'), 1416 'PE' => array(1 => '/^[\x{002d}0-9a-zñáéíóúü]{1,63}$/iu'), 1417 'PL' => array(1 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu', 1418 2 => '/^[\x{002d}а-ик-ш\x{0450}ѓѕјљњќџ]{1,63}$/iu', 1419 3 => '/^[\x{002d}0-9a-zâîăşţ]{1,63}$/iu', 1420 4 => '/^[\x{002d}0-9а-яё\x{04C2}]{1,63}$/iu', 1421 5 => '/^[\x{002d}0-9a-zàáâèéêìíîòóôùúûċġħż]{1,63}$/iu', 1422 6 => '/^[\x{002d}0-9a-zàäåæéêòóôöøü]{1,63}$/iu', 1423 7 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu', 1424 8 => '/^[\x{002d}0-9a-zàáâãçéêíòóôõúü]{1,63}$/iu', 1425 9 => '/^[\x{002d}0-9a-zâîăşţ]{1,63}$/iu', 1426 10=> '/^[\x{002d}0-9a-záäéíóôúýčďĺľňŕšťž]{1,63}$/iu', 1427 11=> '/^[\x{002d}0-9a-zçë]{1,63}$/iu', 1428 12=> '/^[\x{002d}0-9а-ик-шђјљњћџ]{1,63}$/iu', 1429 13=> '/^[\x{002d}0-9a-zćčđšž]{1,63}$/iu', 1430 14=> '/^[\x{002d}0-9a-zâçöûüğış]{1,63}$/iu', 1431 15=> '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu', 1432 16=> '/^[\x{002d}0-9a-zäõöüšž]{1,63}$/iu', 1433 17=> '/^[\x{002d}0-9a-zĉĝĥĵŝŭ]{1,63}$/iu', 1434 18=> '/^[\x{002d}0-9a-zâäéëîô]{1,63}$/iu', 1435 19=> '/^[\x{002d}0-9a-zàáâäåæçèéêëìíîïðñòôöøùúûüýćčłńřśš]{1,63}$/iu', 1436 20=> '/^[\x{002d}0-9a-zäåæõöøüšž]{1,63}$/iu', 1437 21=> '/^[\x{002d}0-9a-zàáçèéìíòóùú]{1,63}$/iu', 1438 22=> '/^[\x{002d}0-9a-zàáéíóöúüőű]{1,63}$/iu', 1439 23=> '/^[\x{002d}0-9ΐά-ώ]{1,63}$/iu', 1440 24=> '/^[\x{002d}0-9a-zàáâåæçèéêëðóôöøüþœ]{1,63}$/iu', 1441 25=> '/^[\x{002d}0-9a-záäéíóöúüýčďěňřšťůž]{1,63}$/iu', 1442 26=> '/^[\x{002d}0-9a-z·àçèéíïòóúü]{1,63}$/iu', 1443 27=> '/^[\x{002d}0-9а-ъьюя\x{0450}\x{045D}]{1,63}$/iu', 1444 28=> '/^[\x{002d}0-9а-яёіў]{1,63}$/iu', 1445 29=> '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu', 1446 30=> '/^[\x{002d}0-9a-záäåæéëíðóöøúüýþ]{1,63}$/iu', 1447 31=> '/^[\x{002d}0-9a-zàâæçèéêëîïñôùûüÿœ]{1,63}$/iu', 1448 32=> '/^[\x{002d}0-9а-щъыьэюяёєіїґ]{1,63}$/iu', 1449 33=> '/^[\x{002d}0-9א-ת]{1,63}$/iu'), 1450 'PR' => array(1 => '/^[\x{002d}0-9a-záéíóúñäëïüöâêîôûàèùæçœãõ]{1,63}$/iu'), 1451 'PT' => array(1 => '/^[\x{002d}0-9a-záàâãçéêíóôõú]{1,63}$/iu'), 1452 'RS' => array(1 => '/^[\x{002D}\x{0030}-\x{0039}\x{0061}-\x{007A}\x{0107}\x{010D}\x{0111}\x{0161}\x{017E}]{1,63}$/iu)'), 1453 'RU' => array(1 => '/^[\x{002d}0-9а-яё]{1,63}$/iu'), 1454 'SA' => array(1 => '/^[\x{002d}.0-9\x{0621}-\x{063A}\x{0641}-\x{064A}\x{0660}-\x{0669}]{1,63}$/iu'), 1455 'SE' => array(1 => '/^[\x{002d}0-9a-zäåéöü]{1,63}$/iu'), 1456 'SH' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'), 1457 'SI' => array( 1458 1 => '/^[\x{002d}0-9a-zà-öø-ÿ]{1,63}$/iu', 1459 2 => '/^[\x{002d}0-9a-zāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĺļľŀłńņňʼnŋōŏőœŕŗřśŝšťŧũūŭůűųŵŷźżž]{1,63}$/iu', 1460 3 => '/^[\x{002d}0-9a-zșț]{1,63}$/iu'), 1461 'SJ' => array(1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'), 1462 'TH' => array(1 => '/^[\x{002d}0-9a-z\x{0E01}-\x{0E3A}\x{0E40}-\x{0E4D}\x{0E50}-\x{0E59}]{1,63}$/iu'), 1463 'TM' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$/iu'), 1464 'TW' => 'Hostname/Cn.php', 1465 'TR' => array(1 => '/^[\x{002d}0-9a-zğıüşöç]{1,63}$/iu'), 1466 'UA' => array(1 => '/^[\x{002d}0-9a-zабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓєѕіїјљњћќѝўџґӂʼ]{1,63}$/iu'), 1467 'VE' => array(1 => '/^[\x{002d}0-9a-záéíóúüñ]{1,63}$/iu'), 1468 'VN' => array(1 => '/^[ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚÝàáâãèéêìíòóôõùúýĂăĐđĨĩŨũƠơƯư\x{1EA0}-\x{1EF9}]{1,63}$/iu'), 1469 'мон' => array(1 => '/^[\x{002d}0-9\x{0430}-\x{044F}]{1,63}$/iu'), 1470 'срб' => array(1 => '/^[\x{002d}0-9а-ик-шђјљњћџ]{1,63}$/iu'), 1471 'сайт' => array(1 => '/^[\x{002d}0-9а-яёіїѝйўґг]{1,63}$/iu'), 1472 'онлайн' => array(1 => '/^[\x{002d}0-9а-яёіїѝйўґг]{1,63}$/iu'), 1473 '中国' => 'Hostname/Cn.php', 1474 '中國' => 'Hostname/Cn.php', 1475 'ලංකා' => array(1 => '/^[\x{0d80}-\x{0dff}]{1,63}$/iu'), 1476 '香港' => 'Hostname/Cn.php', 1477 '台湾' => 'Hostname/Cn.php', 1478 '台灣' => 'Hostname/Cn.php', 1479 'امارات' => 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'), 1480 'الاردن' => 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'), 1481 'السعودية' => 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'), 1482 'ไทย' => array(1 => '/^[\x{002d}0-9a-z\x{0E01}-\x{0E3A}\x{0E40}-\x{0E4D}\x{0E50}-\x{0E59}]{1,63}$/iu'), 1483 'рф' => array(1 => '/^[\x{002d}0-9а-яё]{1,63}$/iu'), 1484 'تونس' => 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'), 1485 'مصر' => 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'), 1486 'இலங்கை' => array(1 => '/^[\x{0b80}-\x{0bff}]{1,63}$/iu'), 1487 'فلسطين' => 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'), 1488 'شبكة' => 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'), 1489 ); 1490 1491 protected $_idnLength = array( 1492 'BIZ' => array(5 => 17, 11 => 15, 12 => 20), 1493 'CN' => array(1 => 20), 1494 'COM' => array(3 => 17, 5 => 20), 1495 'HK' => array(1 => 15), 1496 'INFO'=> array(4 => 17), 1497 'KR' => array(1 => 17), 1498 'NET' => array(3 => 17, 5 => 20), 1499 'ORG' => array(6 => 17), 1500 'TW' => array(1 => 20), 1501 'ایران' => array(1 => 30), 1502 '中国' => array(1 => 20), 1503 '公司' => array(1 => 20), 1504 '网络' => array(1 => 20), 1505 ); 1506 1507 protected $_options = array( 1508 'allow' => self::ALLOW_DNS, 1509 'idn' => true, 1510 'tld' => true, 1511 'ip' => null 1512 ); 1513 1514 /** 1515 * Sets validator options 1516 * 1517 * @see http://www.iana.org/cctld/specifications-policies-cctlds-01apr02.htm Technical Specifications for ccTLDs 1518 * @param array $options Validator options 1519 */ 1520 public function __construct($options = array()) 1521 { 1522 if ($options instanceof Zend_Config) { 1523 $options = $options->toArray(); 1524 } else if (!is_array($options)) { 1525 $options = func_get_args(); 1526 $temp['allow'] = array_shift($options); 1527 if (!empty($options)) { 1528 $temp['idn'] = array_shift($options); 1529 } 1530 1531 if (!empty($options)) { 1532 $temp['tld'] = array_shift($options); 1533 } 1534 1535 if (!empty($options)) { 1536 $temp['ip'] = array_shift($options); 1537 } 1538 1539 $options = $temp; 1540 } 1541 1542 $options += $this->_options; 1543 $this->setOptions($options); 1544 } 1545 1546 /** 1547 * Returns all set options 1548 * 1549 * @return array 1550 */ 1551 public function getOptions() 1552 { 1553 return $this->_options; 1554 } 1555 1556 /** 1557 * Sets the options for this validator 1558 * 1559 * @param array $options 1560 * @return Zend_Validate_Hostname 1561 */ 1562 public function setOptions($options) 1563 { 1564 if (array_key_exists('allow', $options)) { 1565 $this->setAllow($options['allow']); 1566 } 1567 1568 if (array_key_exists('idn', $options)) { 1569 $this->setValidateIdn($options['idn']); 1570 } 1571 1572 if (array_key_exists('tld', $options)) { 1573 $this->setValidateTld($options['tld']); 1574 } 1575 1576 if (array_key_exists('ip', $options)) { 1577 $this->setIpValidator($options['ip']); 1578 } 1579 1580 return $this; 1581 } 1582 1583 /** 1584 * Returns the set ip validator 1585 * 1586 * @return Zend_Validate_Ip 1587 */ 1588 public function getIpValidator() 1589 { 1590 return $this->_options['ip']; 1591 } 1592 1593 /** 1594 * @param Zend_Validate_Ip $ipValidator OPTIONAL 1595 * @return Zend_Validate_Hostname 1596 */ 1597 public function setIpValidator(Zend_Validate_Ip $ipValidator = null) 1598 { 1599 if ($ipValidator === null) { 1600 $ipValidator = new Zend_Validate_Ip(); 1601 } 1602 1603 $this->_options['ip'] = $ipValidator; 1604 return $this; 1605 } 1606 1607 /** 1608 * Returns the allow option 1609 * 1610 * @return integer 1611 */ 1612 public function getAllow() 1613 { 1614 return $this->_options['allow']; 1615 } 1616 1617 /** 1618 * Sets the allow option 1619 * 1620 * @param integer $allow 1621 * @return Zend_Validate_Hostname Provides a fluent interface 1622 */ 1623 public function setAllow($allow) 1624 { 1625 $this->_options['allow'] = $allow; 1626 return $this; 1627 } 1628 1629 /** 1630 * Returns the set idn option 1631 * 1632 * @return boolean 1633 */ 1634 public function getValidateIdn() 1635 { 1636 return $this->_options['idn']; 1637 } 1638 1639 /** 1640 * Set whether IDN domains are validated 1641 * 1642 * This only applies when DNS hostnames are validated 1643 * 1644 * @param boolean $allowed Set allowed to true to validate IDNs, and false to not validate them 1645 * @return $this 1646 */ 1647 public function setValidateIdn ($allowed) 1648 { 1649 $this->_options['idn'] = (bool) $allowed; 1650 return $this; 1651 } 1652 1653 /** 1654 * Returns the set tld option 1655 * 1656 * @return boolean 1657 */ 1658 public function getValidateTld() 1659 { 1660 return $this->_options['tld']; 1661 } 1662 1663 /** 1664 * Set whether the TLD element of a hostname is validated 1665 * 1666 * This only applies when DNS hostnames are validated 1667 * 1668 * @param boolean $allowed Set allowed to true to validate TLDs, and false to not validate them 1669 * @return $this 1670 */ 1671 public function setValidateTld ($allowed) 1672 { 1673 $this->_options['tld'] = (bool) $allowed; 1674 return $this; 1675 } 1676 1677 /** 1678 * Defined by Zend_Validate_Interface 1679 * 1680 * Returns true if and only if the $value is a valid hostname with respect to the current allow option 1681 * 1682 * @param string $value 1683 * @throws Zend_Validate_Exception if a fatal error occurs for validation process 1684 * @return boolean 1685 */ 1686 public function isValid($value) 1687 { 1688 if (!is_string($value)) { 1689 $this->_error(self::INVALID); 1690 return false; 1691 } 1692 1693 $this->_setValue($value); 1694 // Check input against IP address schema 1695 if (preg_match('/^[0-9a-f:.]*$/i', $value) && 1696 $this->_options['ip']->setTranslator($this->getTranslator())->isValid($value)) { 1697 if (!($this->_options['allow'] & self::ALLOW_IP)) { 1698 $this->_error(self::IP_ADDRESS_NOT_ALLOWED); 1699 return false; 1700 } else { 1701 return true; 1702 } 1703 } 1704 1705 // RFC3986 3.2.2 states: 1706 // 1707 // The rightmost domain label of a fully qualified domain name 1708 // in DNS may be followed by a single "." and should be if it is 1709 // necessary to distinguish between the complete domain name and 1710 // some local domain. 1711 // 1712 // (see ZF-6363) 1713 1714 // Local hostnames are allowed to be partitial (ending '.') 1715 if ($this->_options['allow'] & self::ALLOW_LOCAL) { 1716 if (substr($value, -1) === '.') { 1717 $value = substr($value, 0, -1); 1718 if (substr($value, -1) === '.') { 1719 // Empty hostnames (ending '..') are not allowed 1720 $this->_error(self::INVALID_LOCAL_NAME); 1721 return false; 1722 } 1723 } 1724 } 1725 1726 $domainParts = explode('.', $value); 1727 1728 // Prevent partitial IP V4 adresses (ending '.') 1729 if ((count($domainParts) == 4) && preg_match('/^[0-9.a-e:.]*$/i', $value) && 1730 $this->_options['ip']->setTranslator($this->getTranslator())->isValid($value)) { 1731 $this->_error(self::INVALID_LOCAL_NAME); 1732 } 1733 1734 // Check input against DNS hostname schema 1735 if ((count($domainParts) > 1) && (strlen($value) >= 4) && (strlen($value) <= 254)) { 1736 $status = false; 1737 1738 $origenc = PHP_VERSION_ID < 50600 1739 ? iconv_get_encoding('internal_encoding') 1740 : ini_get('default_charset'); 1741 if (PHP_VERSION_ID < 50600) { 1742 iconv_set_encoding('internal_encoding', 'UTF-8'); 1743 } else { 1744 ini_set('default_charset', 'UTF-8'); 1745 } 1746 do { 1747 // First check TLD 1748 $matches = array(); 1749 if (preg_match('/([^.]{2,63})$/iu', end($domainParts), $matches) 1750 || (array_key_exists(end($domainParts), $this->_validIdns))) { 1751 reset($domainParts); 1752 1753 // Hostname characters are: *(label dot)(label dot label); max 254 chars 1754 // label: id-prefix [*ldh{61} id-prefix]; max 63 chars 1755 // id-prefix: alpha / digit 1756 // ldh: alpha / digit / dash 1757 1758 // Match TLD against known list 1759 $this->_tld = $matches[1]; 1760 if ($this->_options['tld']) { 1761 if (!in_array(strtolower($this->_tld), $this->_validTlds) 1762 && !in_array($this->_tld, $this->_validTlds)) { 1763 $this->_error(self::UNKNOWN_TLD); 1764 $status = false; 1765 break; 1766 } 1767 // We have already validated that the TLD is fine. We don't want it to go through the below 1768 // checks as new UTF-8 TLDs will incorrectly fail if there is no IDN regex for it. 1769 array_pop($domainParts); 1770 } 1771 1772 /** 1773 * Match against IDN hostnames 1774 * Note: Keep label regex short to avoid issues with long patterns when matching IDN hostnames 1775 * @see Zend_Validate_Hostname_Interface 1776 */ 1777 $regexChars = array(0 => '/^[a-z0-9\x2d]{1,63}$/i'); 1778 if ($this->_options['idn'] && isset($this->_validIdns[strtoupper($this->_tld)])) { 1779 if (is_string($this->_validIdns[strtoupper($this->_tld)])) { 1780 $regexChars += include($this- >_validIdns[strtoupper($this- >_tld)]); 1781 } else { 1782 $regexChars += $this->_validIdns[strtoupper($this->_tld)]; 1783 } 1784 } 1785 1786 // Check each hostname part 1787 $check = 0; 1788 foreach ($domainParts as $domainPart) { 1789 // If some domain part is empty (i.e. zend..com), it's invalid 1790 if (empty($domainPart) && $domainPart !== '0') { 1791 $this->_error(self::INVALID_HOSTNAME); 1792 return false; 1793 } 1794 1795 // Decode Punycode domainnames to IDN 1796 if (strpos($domainPart, 'xn--') === 0) { 1797 $domainPart = $this->decodePunycode(substr($domainPart, 4)); 1798 if ($domainPart === false) { 1799 return false; 1800 } 1801 } 1802 1803 // Check dash (-) does not start, end or appear in 3rd and 4th positions 1804 if ((strpos($domainPart, '-') === 0) 1805 || ((strlen($domainPart) > 2) && (strpos($domainPart, '-', 2) == 2) && (strpos($domainPart, '-', 3) == 3)) 1806 || (strpos($domainPart, '-') === (strlen($domainPart) - 1))) { 1807 $this->_error(self::INVALID_DASH); 1808 $status = false; 1809 break 2; 1810 } 1811 1812 // Check each domain part 1813 $checked = false; 1814 foreach($regexChars as $regexKey => $regexChar) { 1815 $status = preg_match($regexChar, $domainPart); 1816 if ($status > 0) { 1817 $length = 63; 1818 if (array_key_exists(strtoupper($this->_tld), $this->_idnLength) 1819 && (array_key_exists($regexKey, $this->_idnLength[strtoupper($this->_tld)]))) { 1820 $length = $this->_idnLength[strtoupper($this->_tld)]; 1821 } 1822 1823 if (iconv_strlen($domainPart, 'UTF-8') > $length) { 1824 $this->_error(self::INVALID_HOSTNAME); 1825 } else { 1826 $checked = true; 1827 break; 1828 } 1829 } 1830 } 1831 1832 if ($checked) { 1833 ++$check; 1834 } 1835 } 1836 1837 // If one of the labels doesn't match, the hostname is invalid 1838 if ($check !== count($domainParts)) { 1839 $this->_error(self::INVALID_HOSTNAME_SCHEMA); 1840 $status = false; 1841 } 1842 } else { 1843 // Hostname not long enough 1844 $this->_error(self::UNDECIPHERABLE_TLD); 1845 $status = false; 1846 } 1847 } while (false); 1848 1849 if (PHP_VERSION_ID < 50600) { 1850 iconv_set_encoding('internal_encoding', $origenc); 1851 } else { 1852 ini_set('default_charset', $origenc); 1853 } 1854 // If the input passes as an Internet domain name, and domain names are allowed, then the hostname 1855 // passes validation 1856 if ($status && ($this->_options['allow'] & self::ALLOW_DNS)) { 1857 return true; 1858 } 1859 } else if ($this->_options['allow'] & self::ALLOW_DNS) { 1860 $this->_error(self::INVALID_HOSTNAME); 1861 } 1862 1863 // Check for URI Syntax (RFC3986) 1864 if ($this->_options['allow'] & self::ALLOW_URI) { 1865 if (preg_match("/^([a-zA-Z0-9-._~!$&\'()*+,;=]|%[[:xdigit:]]{2}){1,254}$/i", $value)) { 1866 return true; 1867 } else { 1868 $this->_error(self::INVALID_URI); 1869 } 1870 } 1871 1872 // Check input against local network name schema; last chance to pass validation 1873 $regexLocal = '/^(([a-zA-Z0-9\x2d]{1,63}\x2e)*[a-zA-Z0-9\x2d]{1,63}[\x2e]{0,1}){1,254}$/'; 1874 $status = @preg_match($regexLocal, $value); 1875 1876 // If the input passes as a local network name, and local network names are allowed, then the 1877 // hostname passes validation 1878 $allowLocal = $this->_options['allow'] & self::ALLOW_LOCAL; 1879 if ($status && $allowLocal) { 1880 return true; 1881 } 1882 1883 // If the input does not pass as a local network name, add a message 1884 if (!$status) { 1885 $this->_error(self::INVALID_LOCAL_NAME); 1886 } 1887 1888 // If local network names are not allowed, add a message 1889 if ($status && !$allowLocal) { 1890 $this->_error(self::LOCAL_NAME_NOT_ALLOWED); 1891 } 1892 1893 return false; 1894 } 1895 1896 /** 1897 * Decodes a punycode encoded string to it's original utf8 string 1898 * In case of a decoding failure the original string is returned 1899 * 1900 * @param string $encoded Punycode encoded string to decode 1901 * @return string 1902 */ 1903 protected function decodePunycode($encoded) 1904 { 1905 if (!preg_match('/^[a-z0-9-]+$/i', $encoded)) { 1906 // no punycode encoded string 1907 $this->_error(self::CANNOT_DECODE_PUNYCODE); 1908 return false; 1909 } 1910 1911 $decoded = array(); 1912 $separator = strrpos($encoded, '-'); 1913 if ($separator > 0) { 1914 for ($x = 0; $x < $separator; ++$x) { 1915 // prepare decoding matrix 1916 $decoded[] = ord($encoded[$x]); 1917 } 1918 } 1919 1920 $lengthd = count($decoded); 1921 $lengthe = strlen($encoded); 1922 1923 // decoding 1924 $init = true; 1925 $base = 72; 1926 $index = 0; 1927 $char = 0x80; 1928 1929 for ($indexe = ($separator) ? ($separator + 1) : 0; $indexe < $lengthe; ++$lengthd) { 1930 for ($old_index = $index, $pos = 1, $key = 36; 1 ; $key += 36) { 1931 $hex = ord($encoded[$indexe++]); 1932 $digit = ($hex - 48 < 10) ? $hex - 22 1933 : (($hex - 65 < 26) ? $hex - 65 1934 : (($hex - 97 < 26) ? $hex - 97 1935 : 36)); 1936 1937 $index += $digit * $pos; 1938 $tag = ($key <= $base) ? 1 : (($key >= $base + 26) ? 26 : ($key - $base)); 1939 if ($digit < $tag) { 1940 break; 1941 } 1942 1943 $pos = (int) ($pos * (36 - $tag)); 1944 } 1945 1946 $delta = intval($init ? (($index - $old_index) / 700) : (($index - $old_index) / 2)); 1947 $delta += intval($delta / ($lengthd + 1)); 1948 for ($key = 0; $delta > 910 / 2; $key += 36) { 1949 $delta = intval($delta / 35); 1950 } 1951 1952 $base = intval($key + 36 * $delta / ($delta + 38)); 1953 $init = false; 1954 $char += (int) ($index / ($lengthd + 1)); 1955 $index %= ($lengthd + 1); 1956 if ($lengthd > 0) { 1957 for ($i = $lengthd; $i > $index; $i--) { 1958 $decoded[$i] = $decoded[($i - 1)]; 1959 } 1960 } 1961 1962 $decoded[$index++] = $char; 1963 } 1964 1965 // convert decoded ucs4 to utf8 string 1966 foreach ($decoded as $key => $value) { 1967 if ($value < 128) { 1968 $decoded[$key] = chr($value); 1969 } elseif ($value < (1 << 11)) { 1970 $decoded[$key] = chr(192 + ($value >> 6)); 1971 $decoded[$key] .= chr(128 + ($value & 63)); 1972 } elseif ($value < (1 << 16)) { 1973 $decoded[$key] = chr(224 + ($value >> 12)); 1974 $decoded[$key] .= chr(128 + (($value >> 6) & 63)); 1975 $decoded[$key] .= chr(128 + ($value & 63)); 1976 } elseif ($value < (1 << 21)) { 1977 $decoded[$key] = chr(240 + ($value >> 18)); 1978 $decoded[$key] .= chr(128 + (($value >> 12) & 63)); 1979 $decoded[$key] .= chr(128 + (($value >> 6) & 63)); 1980 $decoded[$key] .= chr(128 + ($value & 63)); 1981 } else { 1982 $this->_error(self::CANNOT_DECODE_PUNYCODE); 1983 return false; 1984 } 1985 } 1986 1987 return implode($decoded); 1988 } 1989 }