From fa0b74f91f6ba4ca7d1be2bf4e534a9299ebbdde Mon Sep 17 00:00:00 2001 From: Marvin Feldmann Date: Tue, 26 Apr 2016 09:49:52 +0200 Subject: [PATCH 1/5] Test Punycoded TLDs --- test/HostnameTest.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/HostnameTest.php b/test/HostnameTest.php index d20282db8..25d26083f 100644 --- a/test/HostnameTest.php +++ b/test/HostnameTest.php @@ -506,6 +506,25 @@ public function testAdditionalUTF8TLDs() } } + public function testAdditionalPunycodedTLDs() + { + $validator = new Hostname(Hostname::ALLOW_ALL); + // Check UTF-8 TLD matching + $valuesExpected = [ + [true, ['test123.xn--80asehdb', 'xn--e1aybc.xn--p1ai', 'xn--h1aggjjdd5b4a.xn--l1acc']], + [false, ['xn--3-owe4au9mpa.xn--xkc2al3hye2a', 'xn--mgbgt.xn--l1acc']] + ]; + foreach ($valuesExpected as $element) { + foreach ($element[1] as $input) { + $this->assertEquals( + $element[0], + $validator->isValid($input), + implode("\n", $validator->getMessages()) .' - '. $input + ); + } + } + } + public function testIDNIT() { $validator = new Hostname(Hostname::ALLOW_ALL); From ab31167d932a1d4b5b1f6711566c86754e3a0dc5 Mon Sep 17 00:00:00 2001 From: Marvin Feldmann Date: Tue, 26 Apr 2016 09:55:21 +0200 Subject: [PATCH 2/5] Punycoded TLD to ASCII --- src/Hostname.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Hostname.php b/src/Hostname.php index f4a580f7b..2f6316ff1 100644 --- a/src/Hostname.php +++ b/src/Hostname.php @@ -1772,8 +1772,16 @@ public function isValid($value) // id-prefix: alpha / digit // ldh: alpha / digit / dash - // Match TLD against known list $this->tld = strtoupper($matches[1]); + // Decode Punycode TLD to IDN + if (strpos($this->tld, 'xn--') === 0) { + $this->tld = $this->decodePunycode(substr($this->tld, 4)); + if ($this->tld === false) { + return false; + } + } + + // Match TLD against known list if ($this->getTldCheck()) { if (!in_array(strtolower($this->tld), $this->validTlds) && !in_array($this->tld, $this->validTlds)) { From 86e023c6180f0881b4bcace30e87d8b3838286e1 Mon Sep 17 00:00:00 2001 From: Marvin Feldmann Date: Tue, 26 Apr 2016 11:40:10 +0200 Subject: [PATCH 3/5] Test with data providers --- test/HostnameTest.php | 72 +++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/test/HostnameTest.php b/test/HostnameTest.php index 25d26083f..ef80e50ba 100644 --- a/test/HostnameTest.php +++ b/test/HostnameTest.php @@ -486,43 +486,55 @@ public function testIDNIL() } } - public function testAdditionalUTF8TLDs() + /** + * Ensures that the validator follows expected behavior for UTF-8 and Punycoded (ACE) TLDs + * + * @dataProvider validTLDHostnames + */ + public function testValidTLDHostnames($value) { - $validator = new Hostname(Hostname::ALLOW_ALL); + $this->assertTrue( + $this->validator->isValid($value), + sprintf( + '%s failed validation: %s', + $value, + implode("\n", $this->validator->getMessages()) + ) + ); + } - // Check UTF-8 TLD matching - $valuesExpected = [ - [true, ['test123.онлайн', 'тест.рф', 'туршилтын.мон']], - [false, ['சோதனை3.இலங்கை', 'رات.мон']] + public function validTLDHostnames() + { + // @codingStandardsIgnoreStart + return [ + 'ASCII label + UTF-8 TLD' => ['test123.онлайн'], + 'ASCII label + Punycoded TLD' => ['test123.xn--80asehdb'], + 'UTF-8 label + UTF-8 TLD (cyrillic)' => ['тест.рф'], + 'Punycoded label + Punycoded TLD (cyrillic)' => ['xn--e1aybc.xn--p1ai'], ]; - foreach ($valuesExpected as $element) { - foreach ($element[1] as $input) { - $this->assertEquals( - $element[0], - $validator->isValid($input), - implode("\n", $validator->getMessages()) .' - '. $input - ); - } - } + // @codingStandardsIgnoreEnd } - public function testAdditionalPunycodedTLDs() + /** + * Ensures that the validator follows expected behavior for invalid UTF-8 and Punycoded (ACE) TLDs + * + * @dataProvider invalidTLDHostnames + */ + public function testInalidTLDHostnames($value) { - $validator = new Hostname(Hostname::ALLOW_ALL); - // Check UTF-8 TLD matching - $valuesExpected = [ - [true, ['test123.xn--80asehdb', 'xn--e1aybc.xn--p1ai', 'xn--h1aggjjdd5b4a.xn--l1acc']], - [false, ['xn--3-owe4au9mpa.xn--xkc2al3hye2a', 'xn--mgbgt.xn--l1acc']] + $this->assertFalse($this->validator->isValid($value)); + } + + public function invalidTLDHostnames() + { + // @codingStandardsIgnoreStart + return [ + 'Invalid mix of UTF-8 and ASCII in label' => ['சோதனை3.இலங்கை'], + 'Invalid mix of UTF-8 and ASCII in label (Punycoded)' => ['xn--3-owe4au9mpa.xn--xkc2al3hye2a'], + 'Invalid use of non-cyrillic characters with cyrillic TLD' => ['رات.мон'], + 'Invalid use of non-cyrillic characters with cyrillic TLD (Punycoded)' => ['xn--mgbgt.xn--l1acc'], ]; - foreach ($valuesExpected as $element) { - foreach ($element[1] as $input) { - $this->assertEquals( - $element[0], - $validator->isValid($input), - implode("\n", $validator->getMessages()) .' - '. $input - ); - } - } + // @codingStandardsIgnoreEnd } public function testIDNIT() From 6e43a59e659b97f353c4f7c1baa4eed2f16f2712 Mon Sep 17 00:00:00 2001 From: Marvin Feldmann Date: Tue, 26 Apr 2016 12:12:41 +0200 Subject: [PATCH 4/5] Make only ASCII TLDs uppercase --- src/Hostname.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Hostname.php b/src/Hostname.php index 2f6316ff1..821e083d7 100644 --- a/src/Hostname.php +++ b/src/Hostname.php @@ -1772,13 +1772,15 @@ public function isValid($value) // id-prefix: alpha / digit // ldh: alpha / digit / dash - $this->tld = strtoupper($matches[1]); + $this->tld = $matches[1]; // Decode Punycode TLD to IDN if (strpos($this->tld, 'xn--') === 0) { $this->tld = $this->decodePunycode(substr($this->tld, 4)); if ($this->tld === false) { return false; } + } else { + $this->tld = strtoupper($this->tld); } // Match TLD against known list From a10e468d54f881ac1f7c61cb7671d7968a51c5f9 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 12 May 2016 14:33:58 -0500 Subject: [PATCH 5/5] Added CHANGELOG for #67 --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ea920a0f..f76807520 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,8 @@ All notable changes to this project will be documented in this file, in reverse ### Added -- Nothing. +- [#67](https://github.com/zendframework/zend-validator/pull/67) adds support + for Punycoded top-level domains in the `Hostname` validator. ### Deprecated