[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/zend/Zend/Validate/ -> Hostname.php (source)

   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  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1