package.xml 0000664 0001750 0001750 00000011551 12517702325 011306 0 ustar jan jan
Horde_Idna
pear.horde.org
IDNA backend normalization package
Normalized access to various backends providing IDNA (Internationalized Domain Names in Applications) support.
Michael Slusarz
slusarz
slusarz@horde.org
yes
2015-04-28
1.0.3
1.0.0
stable
stable
BSD-2-Clause
* [jan] Fix issues with certain locales like Turkish.
5.3.0
6.0.0alpha1
6.0.0alpha1
1.7.0
Horde_Exception
pear.horde.org
2.0.0
3.0.0alpha1
3.0.0alpha1
Horde_Util
pear.horde.org
2.0.0
3.0.0alpha1
3.0.0alpha1
intl
1.0.0
1.0.0
stable
stable
2015-01-07
BSD-2-Clause
* [mms] Initial release.
1.0.1
1.0.0
stable
stable
2015-01-07
BSD-2-Clause
* [jan] Fix install paths (Bug #13785).
1.0.2
1.0.0
stable
stable
2015-04-13
BSD-2-Clause
* [mms] Use intl extension, if installed, and fallback to a locally-patched version of the true/php-punycode package.
1.0.3
1.0.0
stable
stable
2015-04-28
BSD-2-Clause
* [jan] Fix issues with certain locales like Turkish.
Horde_Idna-1.0.3/doc/Horde/Idna/COPYING 0000664 0001750 0001750 00000002463 12517702325 015340 0 ustar jan jan Copyright (c) 2014 TrueServer B.V.
Copyright 2014-2015 Horde LLC. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HORDE PROJECT
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Horde_Idna-1.0.3/lib/Horde/Idna/Exception.php 0000664 0001750 0001750 00000001166 12517702325 016754 0 ustar jan jan
* @category Horde
* @copyright 2014-2015 Horde LLC
* @license http://www.horde.org/licenses/bsd BSD
* @package Idna
*/
class Horde_Idna_Exception extends Horde_Exception
{}
Horde_Idna-1.0.3/lib/Horde/Idna/Punycode.php 0000664 0001750 0001750 00000023632 12517702325 016606 0 ustar jan jan
* @author Michael Slusarz
* @category Horde
* @copyright 2014 TrueServer B.V.
* @copyright 2015 Horde LLC
* @license http://www.horde.org/licenses/bsd BSD
* @link http://tools.ietf.org/html/rfc3492
* @package Idna
*/
class Horde_Idna_Punycode
{
/**
* Bootstring parameter values.
*/
const BASE = 36;
const TMIN = 1;
const TMAX = 26;
const SKEW = 38;
const DAMP = 700;
const INITIAL_BIAS = 72;
const INITIAL_N = 128;
const PREFIX = 'xn--';
const DELIMITER = '-';
/**
* Encode table.
*
* @param array
*/
protected static $_encodeTable = array(
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
);
/**
* Decode table.
*
* @param array
*/
protected static $_decodeTable = array(
'a' => 0, 'b' => 1, 'c' => 2, 'd' => 3, 'e' => 4, 'f' => 5,
'g' => 6, 'h' => 7, 'i' => 8, 'j' => 9, 'k' => 10, 'l' => 11,
'm' => 12, 'n' => 13, 'o' => 14, 'p' => 15, 'q' => 16, 'r' => 17,
's' => 18, 't' => 19, 'u' => 20, 'v' => 21, 'w' => 22, 'x' => 23,
'y' => 24, 'z' => 25, '0' => 26, '1' => 27, '2' => 28, '3' => 29,
'4' => 30, '5' => 31, '6' => 32, '7' => 33, '8' => 34, '9' => 35
);
/**
* Encode a domain to its Punycode version.
*
* @param string $input Domain name in Unicde to be encoded.
*
* @return string Punycode representation in ASCII.
*/
public function encode($input)
{
$parts = explode('.', $input);
foreach ($parts as &$part) {
$part = $this->_encodePart($part);
}
return implode('.', $parts);
}
/**
* Encode a part of a domain name, such as tld, to its Punycode version.
*
* @param string $input Part of a domain name.
*
* @return string Punycode representation of a domain part.
*/
protected function _encodePart($input)
{
$codePoints = $this->_codePoints($input);
$n = static::INITIAL_N;
$bias = static::INITIAL_BIAS;
$delta = 0;
$h = $b = count($codePoints['basic']);
$output = '';
foreach ($codePoints['basic'] as $code) {
$output .= $this->_codePointToChar($code);
}
if ($input === $output) {
return $output;
}
if ($b > 0) {
$output .= static::DELIMITER;
}
$codePoints['nonBasic'] = array_unique($codePoints['nonBasic']);
sort($codePoints['nonBasic']);
$i = 0;
$length = Horde_String::length($input, 'UTF-8');
while ($h < $length) {
$m = $codePoints['nonBasic'][$i++];
$delta = $delta + ($m - $n) * ($h + 1);
$n = $m;
foreach ($codePoints['all'] as $c) {
if (($c < $n) || ($c < static::INITIAL_N)) {
++$delta;
}
if ($c === $n) {
$q = $delta;
for ($k = static::BASE; ; $k += static::BASE) {
$t = $this->_calculateThreshold($k, $bias);
if ($q < $t) {
break;
}
$code = $t + (($q - $t) % (static::BASE - $t));
$output .= static::$_encodeTable[$code];
$q = ($q - $t) / (static::BASE - $t);
}
$output .= static::$_encodeTable[$q];
$bias = $this->_adapt($delta, $h + 1, ($h === $b));
$delta = 0;
++$h;
}
}
++$delta;
++$n;
}
return static::PREFIX . $output;
}
/**
* Decode a Punycode domain name to its Unicode counterpart.
*
* @param string $input Domain name in Punycode
*
* @return string Unicode domain name.
*/
public function decode($input)
{
$parts = explode('.', $input);
foreach ($parts as &$part) {
if (strpos($part, static::PREFIX) === 0) {
$part = $this->_decodePart(
substr($part, strlen(static::PREFIX))
);
}
}
return implode('.', $parts);
}
/**
* Decode a part of domain name, such as tld.
*
* @param string $input Part of a domain name.
*
* @return string Unicode domain part.
*/
protected function _decodePart($input)
{
$n = static::INITIAL_N;
$i = 0;
$bias = static::INITIAL_BIAS;
$output = '';
$pos = strrpos($input, static::DELIMITER);
if ($pos !== false) {
$output = substr($input, 0, $pos++);
} else {
$pos = 0;
}
$outputLength = strlen($output);
$inputLength = strlen($input);
/* Punycode lookup is case-insensitive. */
$input = Horde_String::lower($input);
while ($pos < $inputLength) {
$oldi = $i;
$w = 1;
for ($k = static::BASE; ; $k += static::BASE) {
$digit = static::$_decodeTable[$input[$pos++]];
$i = $i + ($digit * $w);
$t = $this->_calculateThreshold($k, $bias);
if ($digit < $t) {
break;
}
$w = $w * (static::BASE - $t);
}
$bias = $this->_adapt($i - $oldi, ++$outputLength, ($oldi === 0));
$n = $n + (int) ($i / $outputLength);
$i = $i % ($outputLength);
$output = Horde_String::substr($output, 0, $i, 'UTF-8') .
$this->_codePointToChar($n) .
Horde_String::substr($output, $i, $outputLength - 1, 'UTF-8');
++$i;
}
return $output;
}
/**
* Calculate the bias threshold to fall between TMIN and TMAX.
*
* @param integer $k
* @param integer $bias
*
* @return integer
*/
protected function _calculateThreshold($k, $bias)
{
if ($k <= ($bias + static::TMIN)) {
return static::TMIN;
} elseif ($k >= ($bias + static::TMAX)) {
return static::TMAX;
}
return $k - $bias;
}
/**
* Bias adaptation.
*
* @param integer $delta
* @param integer $numPoints
* @param boolean $firstTime
*
* @return integer
*/
protected function _adapt($delta, $numPoints, $firstTime)
{
$delta = (int) (
($firstTime)
? $delta / static::DAMP
: $delta / 2
);
$delta += (int) ($delta / $numPoints);
$k = 0;
while ($delta > ((static::BASE - static::TMIN) * static::TMAX) / 2) {
$delta = (int) ($delta / (static::BASE - static::TMIN));
$k = $k + static::BASE;
}
$k = $k + (int) (((static::BASE - static::TMIN + 1) * $delta) / ($delta + static::SKEW));
return $k;
}
/**
* List code points for a given input.
*
* @param string $input
*
* @return array Multi-dimension array with basic, non-basic and
* aggregated code points.
*/
protected function _codePoints($input)
{
$codePoints = array(
'all' => array(),
'basic' => array(),
'nonBasic' => array()
);
$len = Horde_String::length($input, 'UTF-8');
for ($i = 0; $i < $len; ++$i) {
$char = Horde_String::substr($input, $i, 1, 'UTF-8');
$code = $this->_charToCodePoint($char);
if ($code < 128) {
$codePoints['all'][] = $codePoints['basic'][] = $code;
} else {
$codePoints['all'][] = $codePoints['nonBasic'][] = $code;
}
}
return $codePoints;
}
/**
* Convert a single or multi-byte character to its code point.
*
* @param string $char
*
* @return integer
*/
protected function _charToCodePoint($char)
{
$code = ord($char[0]);
if ($code < 128) {
return $code;
} elseif ($code < 224) {
return (($code - 192) * 64) + (ord($char[1]) - 128);
} elseif ($code < 240) {
return (($code - 224) * 4096) + ((ord($char[1]) - 128) * 64) + (ord($char[2]) - 128);
}
return (($code - 240) * 262144) + ((ord($char[1]) - 128) * 4096) + ((ord($char[2]) - 128) * 64) + (ord($char[3]) - 128);
}
/**
* Convert a code point to its single or multi-byte character
*
* @param integer $code
*
* @return string
*/
protected function _codePointToChar($code)
{
if ($code <= 0x7F) {
return chr($code);
} elseif ($code <= 0x7FF) {
return chr(($code >> 6) + 192) . chr(($code & 63) + 128);
} elseif ($code <= 0xFFFF) {
return chr(($code >> 12) + 224) . chr((($code >> 6) & 63) + 128) . chr(($code & 63) + 128);
}
return chr(($code >> 18) + 240) . chr((($code >> 12) & 63) + 128) . chr((($code >> 6) & 63) + 128) . chr(($code & 63) + 128);
}
}
Horde_Idna-1.0.3/lib/Horde/Idna.php 0000664 0001750 0001750 00000004704 12517702325 015017 0 ustar jan jan
* @category Horde
* @copyright 2014-2015 Horde LLC
* @license http://www.horde.org/licenses/bsd BSD
* @package Idna
*/
class Horde_Idna
{
/**
* The backend to use.
*
* @var mixed
*/
protected static $_backend;
/**
* @throws Horde_Idna_Exception
*/
public static function encode($data)
{
switch ($backend = static::_getBackend()) {
case 'INTL':
return idn_to_ascii($data);
case 'INTL_UTS46':
return idn_to_ascii($data, 0, INTL_IDNA_VARIANT_UTS46);
default:
return $backend->encode($data);
}
}
/**
* @throws Horde_Idna_Exception
*/
public static function decode($data)
{
switch ($backend = static::_getBackend()) {
case 'INTL':
case 'INTL_UTS46':
$parts = explode('.', $data);
foreach ($parts as &$part) {
if (strpos($part, 'xn--') === 0) {
switch ($backend) {
case 'INTL':
$part = idn_to_utf8($part);
break;
case 'INTL_UTS46':
$part = idn_to_utf8($part, 0, INTL_IDNA_VARIANT_UTS46);
break;
}
}
}
return implode('.', $parts);
default:
return $backend->decode($data);
}
}
/**
* Return the IDNA backend.
*
* @return mixed IDNA backend (false if none available).
*/
protected static function _getBackend()
{
if (!isset(self::$_backend)) {
if (extension_loaded('intl')) {
/* Only available in PHP > 5.4.0 */
self::$_backend = defined('INTL_IDNA_VARIANT_UTS46')
? 'INTL_UTS46'
: 'INTL';
} else {
self::$_backend = new Horde_Idna_Punycode();
}
}
return self::$_backend;
}
}
Horde_Idna-1.0.3/test/Horde/Idna/AllTests.php 0000664 0001750 0001750 00000000132 12517702325 016752 0 ustar jan jan run();
Horde_Idna-1.0.3/test/Horde/Idna/bootstrap.php 0000664 0001750 0001750 00000000143 12517702325 017236 0 ustar jan jan assertEquals(
$encoded,
$idna->encode($decoded)
);
}
/**
* @dataProvider domainNamesProvider
*/
public function testDecode($decoded, $encoded)
{
$idna = new Horde_Idna();
$this->assertEquals(
$decoded,
$idna->decode($encoded)
);
}
/**
*/
public function domainNamesProvider()
{
return array(
// http://en.wikipedia.org/wiki/.test_(international_domain_name)#Test_TLDs
array(
'مثال.إختبار',
'xn--mgbh0fb.xn--kgbechtv',
),
array(
'مثال.آزمایشی',
'xn--mgbh0fb.xn--hgbk6aj7f53bba',
),
array(
'例子.测试',
'xn--fsqu00a.xn--0zwm56d',
),
array(
'例子.測試',
'xn--fsqu00a.xn--g6w251d',
),
array(
'пример.испытание',
'xn--e1afmkfd.xn--80akhbyknj4f',
),
array(
'उदाहरण.परीक्षा',
'xn--p1b6ci4b4b3a.xn--11b5bs3a9aj6g',
),
array(
'παράδειγμα.δοκιμή',
'xn--hxajbheg2az3al.xn--jxalpdlp',
),
array(
'실례.테스트',
'xn--9n2bp8q.xn--9t4b11yi5a',
),
array(
'בײַשפּיל.טעסט',
'xn--fdbk5d8ap9b8a8d.xn--deba0ad',
),
array(
'例え.テスト',
'xn--r8jz45g.xn--zckzah',
),
array(
'உதாரணம்.பரிட்சை',
'xn--zkc6cc5bi7f6e.xn--hlcj6aya9esc7a',
),
array(
'derhausüberwacher.de',
'xn--derhausberwacher-pzb.de',
),
array(
'renangonçalves.com',
'xn--renangonalves-pgb.com',
),
array(
'рф.ru',
'xn--p1ai.ru',
),
array(
'δοκιμή.gr',
'xn--jxalpdlp.gr',
),
array(
'ফাহাদ্১৯.বাংলা',
'xn--65bj6btb5gwimc.xn--54b7fta0cc',
),
array(
'𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑.gr',
'xn--uba5533kmaba1adkfh6ch2cg.gr',
),
array(
'guangdong.广东',
'guangdong.xn--xhq521b',
),
array(
'gwóźdź.pl',
'xn--gwd-hna98db.pl',
),
);
}
}
Horde_Idna-1.0.3/test/Horde/Idna/phpunit.xml 0000664 0001750 0001750 00000000056 12517702325 016724 0 ustar jan jan