See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]
1 <?php 2 /** 3 * Copyright 2014-2017 Horde LLC (http://www.horde.org/) 4 * 5 * See the enclosed file LICENSE for license information (BSD). If you 6 * did not receive this file, see http://www.horde.org/licenses/bsd. 7 * 8 * @author Michael Slusarz <slusarz@horde.org> 9 * @category Horde 10 * @license http://www.horde.org/licenses/bsd BSD 11 * @package Idna 12 */ 13 14 /** 15 * Provide normalized encoding/decoding support for IDNA strings. 16 * 17 * @author Michael Slusarz <slusarz@horde.org> 18 * @category Horde 19 * @copyright 2014-2017 Horde LLC 20 * @license http://www.horde.org/licenses/bsd BSD 21 * @package Idna 22 */ 23 class Horde_Idna 24 { 25 /** 26 * The backend to use. 27 * 28 * @var mixed 29 */ 30 protected static $_backend; 31 32 /** 33 * @throws Horde_Idna_Exception 34 */ 35 public static function encode($data) 36 { 37 switch ($backend = static::_getBackend()) { 38 case 'INTL': 39 if ($data === null) { 40 return false; 41 } 42 return idn_to_ascii($data); 43 44 case 'INTL_UTS46': 45 if ($data === null) { 46 return false; 47 } 48 $result = idn_to_ascii($data, 0, INTL_IDNA_VARIANT_UTS46, $info); 49 self::_checkForError($info); 50 return $result; 51 52 default: 53 return $backend->encode($data); 54 } 55 } 56 57 /** 58 * @throws Horde_Idna_Exception 59 */ 60 public static function decode($data) 61 { 62 switch ($backend = static::_getBackend()) { 63 case 'INTL': 64 case 'INTL_UTS46': 65 $parts = explode('.', $data); 66 foreach ($parts as &$part) { 67 if (strpos($part, 'xn--') === 0) { 68 switch ($backend) { 69 case 'INTL': 70 $part = idn_to_utf8($part); 71 break; 72 73 case 'INTL_UTS46': 74 $part = idn_to_utf8($part, 0, INTL_IDNA_VARIANT_UTS46, $info); 75 self::_checkForError($info); 76 break; 77 } 78 } 79 } 80 return implode('.', $parts); 81 82 default: 83 return $backend->decode($data); 84 } 85 } 86 87 /** 88 * Checks if the $idna_info parameter of idn_to_ascii() or idn_to_utf8() 89 * contains errors. 90 * 91 * @param array $info Fourth parameter to idn_to_ascii() or idn_to_utf8(). 92 * 93 * @throws Horde_Idna_Exception 94 */ 95 protected static function _checkForError($info) 96 { 97 if (!isset($info['errors'])) { 98 return; 99 } 100 switch (true) { 101 case $info['errors'] & IDNA_ERROR_EMPTY_LABEL: 102 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 103 "Domain name is empty" 104 )); 105 case $info['errors'] & IDNA_ERROR_LABEL_TOO_LONG: 106 case $info['errors'] & IDNA_ERROR_DOMAIN_NAME_TOO_LONG: 107 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 108 "Domain name is too long" 109 )); 110 case $info['errors'] & IDNA_ERROR_LEADING_HYPHEN: 111 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 112 "Starts with a hyphen" 113 )); 114 case $info['errors'] & IDNA_ERROR_TRAILING_HYPHEN: 115 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 116 "Ends with a hyphen" 117 )); 118 case $info['errors'] & IDNA_ERROR_HYPHEN_3_4: 119 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 120 "Contains hyphen in the third and fourth positions" 121 )); 122 case $info['errors'] & IDNA_ERROR_LEADING_COMBINING_MARK: 123 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 124 "Starts with a combining mark" 125 )); 126 case $info['errors'] & IDNA_ERROR_DISALLOWED: 127 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 128 "Contains disallowed characters" 129 )); 130 case $info['errors'] & IDNA_ERROR_PUNYCODE: 131 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 132 "Starts with \"xn--\" but does not contain valid Punycode" 133 )); 134 case $info['errors'] & IDNA_ERROR_LABEL_HAS_DOT: 135 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 136 "Contains a dot" 137 )); 138 case $info['errors'] & IDNA_ERROR_INVALID_ACE_LABEL: 139 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 140 "ACE label does not contain a valid label string" 141 )); 142 case $info['errors'] & IDNA_ERROR_BIDI: 143 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 144 "Does not meet the IDNA BiDi requirements (for right-to-left characters)" 145 )); 146 case $info['errors'] & IDNA_ERROR_CONTEXTJ: 147 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 148 "Does not meet the IDNA CONTEXTJ requirements" 149 )); 150 case $info['errors']: 151 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 152 "Unknown error" 153 )); 154 } 155 } 156 157 /** 158 * Return the IDNA backend. 159 * 160 * @return mixed IDNA backend (false if none available). 161 */ 162 protected static function _getBackend() 163 { 164 if (!isset(self::$_backend)) { 165 if (extension_loaded('intl')) { 166 /* Only available in PHP > 5.4.0 */ 167 self::$_backend = defined('INTL_IDNA_VARIANT_UTS46') 168 ? 'INTL_UTS46' 169 : 'INTL'; 170 } else { 171 self::$_backend = new Horde_Idna_Punycode(); 172 } 173 } 174 175 return self::$_backend; 176 } 177 178 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body