Skip to content
This repository has been archived by the owner on Jul 25, 2022. It is now read-only.

Commit

Permalink
Merge pull request #20 from skroczek/rfc-compliance
Browse files Browse the repository at this point in the history
Increase rfc compliance
  • Loading branch information
ceeram authored Aug 9, 2016
2 parents e84aa47 + 7c781cc commit 8d42d0a
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 3 deletions.
13 changes: 13 additions & 0 deletions src/Exception/DomainOutOfBoundsException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace TrueBV\Exception;

/**
* Class DomainOutOfBoundsException
* @package TrueBV\Exception
* @author Sebastian Kroczek <sk@xbug.de>
*/
class DomainOutOfBoundsException extends OutOfBoundsException
{

}
13 changes: 13 additions & 0 deletions src/Exception/LabelOutOfBoundsException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace TrueBV\Exception;

/**
* Class LabelOutOfBoundsException
* @package TrueBV\Exception
* @author Sebastian Kroczek <sk@xbug.de>
*/
class LabelOutOfBoundsException extends OutOfBoundsException
{

}
13 changes: 13 additions & 0 deletions src/Exception/OutOfBoundsException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace TrueBV\Exception;

/**
* Class OutOfBoundsException
* @package TrueBV\Exception
* @author Sebastian Kroczek <sk@xbug.de>
*/
class OutOfBoundsException extends \RuntimeException
{

}
32 changes: 29 additions & 3 deletions src/Punycode.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<?php
namespace TrueBV;

use TrueBV\Exception\DomainOutOfBoundsException;
use TrueBV\Exception\LabelOutOfBoundsException;

/**
* Punycode implementation as described in RFC 3492
*
Expand Down Expand Up @@ -76,10 +79,19 @@ public function encode($input)
$input = mb_strtolower($input, $this->encoding);
$parts = explode('.', $input);
foreach ($parts as &$part) {
$length = strlen($part);
if ($length < 1) {
throw new LabelOutOfBoundsException(sprintf('The length of any one label is limited to between 1 and 63 octets, but %s given.', $length));
}
$part = $this->encodePart($part);
}
$output = implode('.', $parts);
$length = strlen($output);
if ($length > 255) {
throw new DomainOutOfBoundsException(sprintf('A full domain name is limited to 255 octets (including the separators), %s given.', $length));
}

return implode('.', $parts);
return $output;
}

/**
Expand Down Expand Up @@ -146,8 +158,13 @@ protected function encodePart($input)
$delta++;
$n++;
}
$out = static::PREFIX . $output;
$length = strlen($out);
if ($length > 63 || $length < 1) {
throw new LabelOutOfBoundsException(sprintf('The length of any one label is limited to between 1 and 63 octets, but %s given.', $length));
}

return static::PREFIX . $output;
return $out;
}

/**
Expand All @@ -161,15 +178,24 @@ public function decode($input)
$input = strtolower($input);
$parts = explode('.', $input);
foreach ($parts as &$part) {
$length = strlen($part);
if ($length > 63 || $length < 1) {
throw new LabelOutOfBoundsException(sprintf('The length of any one label is limited to between 1 and 63 octets, but %s given.', $length));
}
if (strpos($part, static::PREFIX) !== 0) {
continue;
}

$part = substr($part, strlen(static::PREFIX));
$part = $this->decodePart($part);
}
$output = implode('.', $parts);
$length = strlen($output);
if ($length > 255) {
throw new DomainOutOfBoundsException(sprintf('A full domain name is limited to 255 octets (including the separators), %s given.', $length));
}

return implode('.', $parts);
return $output;
}

/**
Expand Down
103 changes: 103 additions & 0 deletions tests/PunycodeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,107 @@ public function domainNamesProvider()
),
);
}

/**
* Test encoding Punycode with invalid domains
*
* @param string $decoded Decoded domain
* @param string $exception
* @param string $message
*
* @dataProvider invalidUtf8DomainNamesProvider
*/
public function testEncodeInvalid($decoded, $exception, $message)
{
$Punycode = new Punycode();
$ex = null;

try {
$Punycode->encode($decoded);
} catch (\Exception $e) {
$ex = $e;
}

$this->assertNotNull($ex);
$this->assertInstanceOf($exception, $ex);
$this->assertEquals($message, $ex->getMessage());
}

/**
* Provide invalid domain names containing the decoded names
*
* @return array
*/
public function invalidUtf8DomainNamesProvider()
{
return array(
array(
'äöüßáàăâåãąāæćĉčċçďđéèĕêěëėęēğĝġģĥħíìĭîïĩįīıĵķĺľļłńňñņŋóòŏôőõøōœĸŕřŗśŝšşťţŧúùŭûůűũųūŵýŷÿźžżðþ.de',
'\TrueBV\Exception\LabelOutOfBoundsException',
'The length of any one label is limited to between 1 and 63 octets, but 167 given.',
),
array(
'aaaaa.aaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaa.äöüßáàăâåãąāæćĉčċçďđéèĕêěëėęēğĝġģĥ.ħíìĭîïĩįīıĵķĺľļłńňñņŋóòŏôőõ.øōœĸŕřŗśŝšşťţŧúùŭûůűũųū.ŵýŷÿźžżðþ.de',
'\TrueBV\Exception\DomainOutOfBoundsException',
'A full domain name is limited to 255 octets (including the separators), 258 given.',
),
array(
'aa..aa.de',
'\TrueBV\Exception\LabelOutOfBoundsException',
'The length of any one label is limited to between 1 and 63 octets, but 0 given.',
),

);
}

/**
* Test decoding Punycode with invalid domains
*
* @param string $encoded Encoded domain
* @param string $exception
* @param string $message
*
* @dataProvider invalidAsciiDomainNameProvider
*/
public function testDecodeInvalid($encoded, $exception, $message)
{
$Punycode = new Punycode();
$ex = null;

try {
$Punycode->decode($encoded);
} catch (\Exception $e) {
$ex = $e;
}

$this->assertNotNull($ex);
$this->assertInstanceOf($exception, $ex);
$this->assertEquals($message, $ex->getMessage());
}

/**
* Provide invalid domain names containing the encoded names
*
* @return array
*/
public function invalidAsciiDomainNameProvider()
{
return array(
array(
'xn--zcaccffbljjkknnoorrssuuxxd5e0a0a3ae9c6a4a9bzdzdxdudwdxd2d2d8d0dse7d6dwe9dxeueweye4eyewe9e5ewkkewc9ftfpfplwexfwf4infvf2f6f6f7f8fpg8fmgngrgrgvgzgygxg3gyg1g3g5gykqg9g.de',
'\TrueBV\Exception\LabelOutOfBoundsException',
'The length of any one label is limited to between 1 and 63 octets, but 167 given.',
),
array(
'xn--zcaccffbljjkknnoorrssuuxxd5e0a0a3ae9c8c1b0dxdvdvdxdvd3d0d6dyd8d5d4due7dveseuewe2eweue7e3esk9dxc7frf9e7kuevfuf1ilftf5f4f4f5f6fng6f8f9fpgpgtgxgwgvg1g2gzg1g3gvkog7g.xn--vda.de',
'\TrueBV\Exception\LabelOutOfBoundsException',
'The length of any one label is limited to between 1 and 63 octets, but 165 given.',
),
array(
'aaaaa.aaaaaaaaaaaaaaa.aaaaaaaaaaaaa.aaaaaaaaaaaaaaaa.aaaaaaaaaa.xn--zcaccffbljjkknn6lsd0d4a3b2b2b4b4byc8b0c8b4c0czcwd3c9c8c8c.xn--ddabeekggjj50c0ayw5a5a8d8a6cxb1bzfzb8b7bze8e8b.xn--pdaccf61ajetbrstxy0a1a5a5a9a2b0bzb6b5b8b.xn--hdazec20dnawqr.de',
'\TrueBV\Exception\DomainOutOfBoundsException',
'A full domain name is limited to 255 octets (including the separators), 256 given.',
),
);
}
}

0 comments on commit 8d42d0a

Please sign in to comment.