Commit 5c6746e4 authored by Kevin Fischer's avatar Kevin Fischer

[breaking] replace improper validation in IdnaConvert::decode(); make...

[breaking] replace improper validation in IdnaConvert::decode(); make Punycode::decode() return false instead of raising an exception when early validation fails
parent 7febee9f
......@@ -58,8 +58,6 @@ class IdnaConvert {
const SubVersion = 'main';
// Internal settings, do not touch!
const PunycodePrefix = 'xn--';
protected $encoding = 'utf8'; // Default input charset is UTF-8
protected $strictMode = false; // Behave strict or not
protected $idnVersion = '2008'; // Can be either 2003 (old) or 2008 (default)
......@@ -203,21 +201,17 @@ class IdnaConvert {
list ($email_pref, $input) = explode('@', $input, 2);
$arr = explode('.', $input);
foreach ($arr as $k => $v) {
if (preg_match('!^' . preg_quote(self::PunycodePrefix, '!') . '!', $v)) {
$conv = $punyCode->decode($v);
if ($conv) {
$arr[$k] = $conv;
}
$conv = $punyCode->decode($v);
if ($conv) {
$arr[$k] = $conv;
}
}
$input = join('.', $arr);
$arr = explode('.', $email_pref);
foreach ($arr as $k => $v) {
if (preg_match('!^' . preg_quote(self::PunycodePrefix, '!') . '!', $v)) {
$conv = $punyCode->decode($v);
if ($conv) {
$arr[$k] = $conv;
}
$conv = $punyCode->decode($v);
if ($conv) {
$arr[$k] = $conv;
}
}
$email_pref = join('.', $arr);
......@@ -248,7 +242,9 @@ class IdnaConvert {
$arr = explode('.', $input);
foreach ($arr as $k => $v) {
$conv = $punyCode->decode($v);
$arr[$k] = ($conv) ? $conv : $v;
if ($conv) {
$arr[$k] = $conv;
}
}
$return = join('.', $arr);
}
......
......@@ -77,11 +77,32 @@ class Punycode implements PunycodeInterface
$this->UnicodeTranscoder = $UnicodeTranscoder;
}
/**
* Returns the used prefix for punycode-encoded strings
* @return string
*/
public function getPunycodePrefix()
{
return self::punycodePrefix;
}
/**
* Checks, whether or not the provided string is a valid punycode string
* @param string $encoded
* @return boolean
*/
public function validate($encoded) {
// Check for existence of the prefix
if (strpos($encoded, self::punycodePrefix) !== 0) {
return false;
}
// If nothing is left after the prefix, it is hopeless
if (strlen(trim($encoded)) <= strlen(self::punycodePrefix)) {
return false;
}
return true;
}
/**
* The actual decoding algorithm
* @param string
......@@ -89,16 +110,11 @@ class Punycode implements PunycodeInterface
*/
public function decode($encoded)
{
$decoded = [];
// find the Punycode prefix
if (!preg_match('!^' . preg_quote(self::punycodePrefix, '!') . '!', $encoded)) {
throw new \InvalidArgumentException('This is not a punycode string');
}
$encode_test = preg_replace('!^' . preg_quote(self::punycodePrefix, '!') . '!', '', $encoded);
// If nothing left after removing the prefix, it is hopeless
if (!$encode_test) {
if (!$this->validate($encoded)) {
return false;
}
$decoded = [];
// Find last occurence of the delimiter
$delim_pos = strrpos($encoded, '-');
if ($delim_pos > self::byteLength(self::punycodePrefix)) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment