Skip to content

Commit

Permalink
fix: use symfony/polyfill-mbstring to correct issues in Hostname vali…
Browse files Browse the repository at this point in the history
…dator

This patch adds symfony/polyfill-mbstring as a requirement, and updates the `Hostname` validator to use mbstring equivalents of various string operations, where they are available.

Locally, one of the two new tests passes, but one original test ("UTF-8 label + UTF-8 TLD (cyrillic)") now fails — which may be a problem with my own locale.

Signed-off-by: Matthew Weier O'Phinney <[email protected]>
  • Loading branch information
weierophinney committed Jan 6, 2021
1 parent 6620fa2 commit 1031676
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 12 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
"php": "^7.3 || ~8.0.0",
"container-interop/container-interop": "^1.1",
"laminas/laminas-stdlib": "^3.3",
"laminas/laminas-zendframework-bridge": "^1.0"
"laminas/laminas-zendframework-bridge": "^1.0",
"symfony/polyfill-mbstring": "^1.20"
},
"require-dev": {
"laminas/laminas-cache": "^2.6.1",
Expand Down
22 changes: 11 additions & 11 deletions src/Hostname.php
Original file line number Diff line number Diff line change
Expand Up @@ -1965,8 +1965,8 @@ public function isValid($value)

$this->setValue($value);
// Check input against IP address schema
if (((preg_match('/^[0-9.]*$/', $value) && strpos($value, '.') !== false)
|| (preg_match('/^[0-9a-f:.]*$/i', $value) && strpos($value, ':') !== false))
if (((preg_match('/^[0-9.]*$/', $value) && mb_strpos($value, '.') !== false)
|| (preg_match('/^[0-9a-f:.]*$/i', $value) && mb_strpos($value, ':') !== false))
&& $this->getIpValidator()->setTranslator($this->getTranslator())->isValid($value)
) {
if (! ($this->getAllow() & self::ALLOW_IP)) {
Expand All @@ -1987,9 +1987,9 @@ public function isValid($value)

// Local hostnames are allowed to be partial (ending '.')
if ($this->getAllow() & self::ALLOW_LOCAL) {
if (substr($value, -1) === '.') {
$value = substr($value, 0, -1);
if (substr($value, -1) === '.') {
if (mb_substr($value, -1) === '.') {
$value = mb_substr($value, 0, -1);
if (mb_substr($value, -1) === '.') {
// Empty hostnames (ending '..') are not allowed
$this->error(self::INVALID_LOCAL_NAME);
return false;
Expand Down Expand Up @@ -2031,18 +2031,18 @@ public function isValid($value)
$this->tld = $matches[1];
// Decode Punycode TLD to IDN
if (strpos($this->tld, 'xn--') === 0) {
$this->tld = $this->decodePunycode(substr($this->tld, 4));
$this->tld = $this->decodePunycode(mb_substr($this->tld, 4));
if ($this->tld === false) {
return false;
}
} else {
$this->tld = strtoupper($this->tld);
$this->tld = mb_strtoupper($this->tld);
}

// Match TLD against known list
$removedTld = false;
if ($this->getTldCheck()) {
if (! in_array(strtolower($this->tld), $this->validTlds)
if (! in_array(mb_strtolower($this->tld), $this->validTlds)
&& ! in_array($this->tld, $this->validTlds)) {
$this->error(self::UNKNOWN_TLD);
$status = false;
Expand Down Expand Up @@ -2078,7 +2078,7 @@ public function isValid($value)
foreach ($domainParts as $domainPart) {
// Decode Punycode domain names to IDN
if (strpos($domainPart, 'xn--') === 0) {
$domainPart = $this->decodePunycode(substr($domainPart, 4));
$domainPart = $this->decodePunycode(mb_substr($domainPart, 4));
if ($domainPart === false) {
return false;
}
Expand Down Expand Up @@ -2203,7 +2203,7 @@ protected function decodePunycode($encoded)
}

$decoded = [];
$separator = strrpos($encoded, '-');
$separator = mb_strrpos($encoded, '-');
if ($separator > 0) {
for ($x = 0; $x < $separator; ++$x) {
// prepare decoding matrix
Expand All @@ -2212,7 +2212,7 @@ protected function decodePunycode($encoded)
}

$lengthd = count($decoded);
$lengthe = strlen($encoded);
$lengthe = mb_strlen($encoded);

// decoding
$init = true;
Expand Down

0 comments on commit 1031676

Please sign in to comment.