Differences Between: [Versions 310 and 400] [Versions 39 and 400] [Versions 400 and 401] [Versions 400 and 402] [Versions 400 and 403]
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 return idn_to_ascii($data); 40 41 case 'INTL_UTS46': 42 $result = idn_to_ascii($data, 0, INTL_IDNA_VARIANT_UTS46, $info); 43 self::_checkForError($info); 44 return $result; 45 46 default: 47 return $backend->encode($data); 48 } 49 } 50 51 /** 52 * @throws Horde_Idna_Exception 53 */ 54 public static function decode($data) 55 { 56 switch ($backend = static::_getBackend()) { 57 case 'INTL': 58 case 'INTL_UTS46': 59 $parts = explode('.', $data); 60 foreach ($parts as &$part) { 61 if (strpos($part, 'xn--') === 0) { 62 switch ($backend) { 63 case 'INTL': 64 $part = idn_to_utf8($part); 65 break; 66 67 case 'INTL_UTS46': 68 $part = idn_to_utf8($part, 0, INTL_IDNA_VARIANT_UTS46, $info); 69 self::_checkForError($info); 70 break; 71 } 72 } 73 } 74 return implode('.', $parts); 75 76 default: 77 return $backend->decode($data); 78 } 79 } 80 81 /** 82 * Checks if the $idna_info parameter of idn_to_ascii() or idn_to_utf8() 83 * contains errors. 84 * 85 * @param array $info Fourth parameter to idn_to_ascii() or idn_to_utf8(). 86 * 87 * @throws Horde_Idna_Exception 88 */ 89 protected static function _checkForError($info) 90 { 91 if (!isset($info['errors'])) { 92 return; 93 } 94 switch (true) { 95 case $info['errors'] & IDNA_ERROR_EMPTY_LABEL: 96 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 97 "Domain name is empty" 98 )); 99 case $info['errors'] & IDNA_ERROR_LABEL_TOO_LONG: 100 case $info['errors'] & IDNA_ERROR_DOMAIN_NAME_TOO_LONG: 101 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 102 "Domain name is too long" 103 )); 104 case $info['errors'] & IDNA_ERROR_LEADING_HYPHEN: 105 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 106 "Starts with a hyphen" 107 )); 108 case $info['errors'] & IDNA_ERROR_TRAILING_HYPHEN: 109 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 110 "Ends with a hyphen" 111 )); 112 case $info['errors'] & IDNA_ERROR_HYPHEN_3_4: 113 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 114 "Contains hyphen in the third and fourth positions" 115 )); 116 case $info['errors'] & IDNA_ERROR_LEADING_COMBINING_MARK: 117 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 118 "Starts with a combining mark" 119 )); 120 case $info['errors'] & IDNA_ERROR_DISALLOWED: 121 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 122 "Contains disallowed characters" 123 )); 124 case $info['errors'] & IDNA_ERROR_PUNYCODE: 125 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 126 "Starts with \"xn--\" but does not contain valid Punycode" 127 )); 128 case $info['errors'] & IDNA_ERROR_LABEL_HAS_DOT: 129 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 130 "Contains a dot" 131 )); 132 case $info['errors'] & IDNA_ERROR_INVALID_ACE_LABEL: 133 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 134 "ACE label does not contain a valid label string" 135 )); 136 case $info['errors'] & IDNA_ERROR_BIDI: 137 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 138 "Does not meet the IDNA BiDi requirements (for right-to-left characters)" 139 )); 140 case $info['errors'] & IDNA_ERROR_CONTEXTJ: 141 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 142 "Does not meet the IDNA CONTEXTJ requirements" 143 )); 144 case $info['errors']: 145 throw new Horde_Idna_Exception(Horde_Idna_Translation::t( 146 "Unknown error" 147 )); 148 } 149 } 150 151 /** 152 * Return the IDNA backend. 153 * 154 * @return mixed IDNA backend (false if none available). 155 */ 156 protected static function _getBackend() 157 { 158 if (!isset(self::$_backend)) { 159 if (extension_loaded('intl')) { 160 /* Only available in PHP > 5.4.0 */ 161 self::$_backend = defined('INTL_IDNA_VARIANT_UTS46') 162 ? 'INTL_UTS46' 163 : 'INTL'; 164 } else { 165 self::$_backend = new Horde_Idna_Punycode(); 166 } 167 } 168 169 return self::$_backend; 170 } 171 172 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body