|   1:  | <?php | 
|   2:  |  | 
|   3:  |  | 
|   4:  |  | 
|   5:  |  | 
|   6:  | class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef | 
|   7:  | { | 
|   8:  |  | 
|   9:  |      | 
|  10:  |  | 
|  11:  |  | 
|  12:  |  | 
|  13:  |     protected $ipv4; | 
|  14:  |  | 
|  15:  |      | 
|  16:  |  | 
|  17:  |  | 
|  18:  |  | 
|  19:  |     protected $ipv6; | 
|  20:  |  | 
|  21:  |     public function __construct() | 
|  22:  |     { | 
|  23:  |         $this->ipv4 = new HTMLPurifier_AttrDef_URI_IPv4(); | 
|  24:  |         $this->ipv6 = new HTMLPurifier_AttrDef_URI_IPv6(); | 
|  25:  |     } | 
|  26:  |  | 
|  27:  |      | 
|  28:  |  | 
|  29:  |  | 
|  30:  |  | 
|  31:  |  | 
|  32:  |  | 
|  33:  |     public function validate($string, $config, $context) | 
|  34:  |     { | 
|  35:  |         $length = strlen($string); | 
|  36:  |          | 
|  37:  |          | 
|  38:  |          | 
|  39:  |          | 
|  40:  |          | 
|  41:  |          | 
|  42:  |         if ($string === '') { | 
|  43:  |             return ''; | 
|  44:  |         } | 
|  45:  |         if ($length > 1 && $string[0] === '[' && $string[$length - 1] === ']') { | 
|  46:  |              | 
|  47:  |             $ip = substr($string, 1, $length - 2); | 
|  48:  |             $valid = $this->ipv6->validate($ip, $config, $context); | 
|  49:  |             if ($valid === false) { | 
|  50:  |                 return false; | 
|  51:  |             } | 
|  52:  |             return '[' . $valid . ']'; | 
|  53:  |         } | 
|  54:  |  | 
|  55:  |          | 
|  56:  |         $ipv4 = $this->ipv4->validate($string, $config, $context); | 
|  57:  |         if ($ipv4 !== false) { | 
|  58:  |             return $ipv4; | 
|  59:  |         } | 
|  60:  |  | 
|  61:  |          | 
|  62:  |  | 
|  63:  |          | 
|  64:  |          | 
|  65:  |  | 
|  66:  |          | 
|  67:  |          | 
|  68:  |          | 
|  69:  |          | 
|  70:  |          | 
|  71:  |          | 
|  72:  |          | 
|  73:  |          | 
|  74:  |          | 
|  75:  |          | 
|  76:  |          | 
|  77:  |         $underscore = $config->get('Core.AllowHostnameUnderscore') ? '_' : ''; | 
|  78:  |  | 
|  79:  |          | 
|  80:  |          | 
|  81:  |          | 
|  82:  |         $a   = '[a-z]';      | 
|  83:  |         $an  = '[a-z0-9]';   | 
|  84:  |         $and = "[a-z0-9-$underscore]";  | 
|  85:  |          | 
|  86:  |         $domainlabel = "$an(?:$and*$an)?"; | 
|  87:  |          | 
|  88:  |          | 
|  89:  |          | 
|  90:  |         $toplabel = "$an(?:$and*$an)?"; | 
|  91:  |          | 
|  92:  |         if (preg_match("/^(?:$domainlabel\.)*($toplabel)\.?$/i", $string, $matches)) { | 
|  93:  |             if (!ctype_digit($matches[1])) { | 
|  94:  |                 return $string; | 
|  95:  |             } | 
|  96:  |         } | 
|  97:  |  | 
|  98:  |          | 
|  99:  |         if (function_exists('idn_to_ascii')) { | 
| 100:  |             if (defined('IDNA_NONTRANSITIONAL_TO_ASCII') && defined('INTL_IDNA_VARIANT_UTS46')) { | 
| 101:  |                 $string = idn_to_ascii($string, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46); | 
| 102:  |             } else { | 
| 103:  |                 $string = idn_to_ascii($string); | 
| 104:  |             } | 
| 105:  |  | 
| 106:  |          | 
| 107:  |          | 
| 108:  |          | 
| 109:  |         } elseif ($config->get('Core.EnableIDNA')) { | 
| 110:  |             $idna = new Net_IDNA2(array('encoding' => 'utf8', 'overlong' => false, 'strict' => true)); | 
| 111:  |              | 
| 112:  |             $parts = explode('.', $string); | 
| 113:  |             try { | 
| 114:  |                 $new_parts = array(); | 
| 115:  |                 foreach ($parts as $part) { | 
| 116:  |                     $encodable = false; | 
| 117:  |                     for ($i = 0, $c = strlen($part); $i < $c; $i++) { | 
| 118:  |                         if (ord($part[$i]) > 0x7a) { | 
| 119:  |                             $encodable = true; | 
| 120:  |                             break; | 
| 121:  |                         } | 
| 122:  |                     } | 
| 123:  |                     if (!$encodable) { | 
| 124:  |                         $new_parts[] = $part; | 
| 125:  |                     } else { | 
| 126:  |                         $new_parts[] = $idna->encode($part); | 
| 127:  |                     } | 
| 128:  |                 } | 
| 129:  |                 $string = implode('.', $new_parts); | 
| 130:  |             } catch (Exception $e) { | 
| 131:  |                  | 
| 132:  |             } | 
| 133:  |         } | 
| 134:  |          | 
| 135:  |         if (preg_match("/^($domainlabel\.)*$toplabel\.?$/i", $string)) { | 
| 136:  |             return $string; | 
| 137:  |         } | 
| 138:  |         return false; | 
| 139:  |     } | 
| 140:  | } | 
| 141:  |  | 
| 142:  |  | 
| 143:  |  |