From 33b242f748554ba6ddec0d5a4fda1d882f0423eb Mon Sep 17 00:00:00 2001 From: Michael M Slusarz Date: Thu, 5 Feb 2009 22:54:24 -0700 Subject: [PATCH] Request #5836: Decode IDN (RFC 3490) names. --- framework/Mime/lib/Horde/Mime/Address.php | 87 ++++++++++++++++++++++--------- framework/Mime/package.xml | 7 ++- 2 files changed, 69 insertions(+), 25 deletions(-) diff --git a/framework/Mime/lib/Horde/Mime/Address.php b/framework/Mime/lib/Horde/Mime/Address.php index d798f469b..08dd3c6f4 100644 --- a/framework/Mime/lib/Horde/Mime/Address.php +++ b/framework/Mime/lib/Horde/Mime/Address.php @@ -1,7 +1,7 @@ + * 'idn' - (boolean) Convert IDN domain names (Punycode/RFC 3490) into + * the local charset. + * Requires the PECL idn module. + * DEFAULT: true + * * * @return string The correctly escaped and quoted * "$personal <$mailbox@$host>" string. */ - static public function writeAddress($mailbox, $host, $personal = '') + static public function writeAddress($mailbox, $host, $personal = '', + $opts = array()) { $address = ''; @@ -32,7 +40,14 @@ class Horde_Mime_Address $address .= self::encode($personal, 'personal') . ' <'; } - $address .= self::encode($mailbox, 'address') . '@' . ltrim($host, '@'); + $host = ltrim($host, '@'); + if ((!isset($opts['idn']) || !$opts['idn']) && + (stripos($host, 'xn--') === 0) && + Util::extensionExists('idn')) { + $host = String::convertCharset(idn_to_utf8($host), 'UTF-8'); + } + + $address .= self::encode($mailbox, 'address') . '@' . $host; if (strlen($personal)) { $address .= '>'; @@ -138,15 +153,22 @@ class Horde_Mime_Address * 'host' = The host the mailbox is on ("example.com") * * - * @param array $ob The address object to be turned into a string. - * @param mixed $filter A user@example.com style bare address to ignore. - * Either single string or an array of strings. If - * the address matches $filter, an empty string will - * be returned. + * @param array $ob The address object to be turned into a string. + * @param array $opts Additional options: + *
+     * 'filter' - (mixed) A user@example.com style bare address to ignore.
+     *            Either single string or an array of strings. If the address
+     *            matches $filter, an empty string will be returned.
+     *            DEFAULT: No filter
+     * 'idn' - (boolean) Convert IDN domain names (Punycode/RFC 3490) into
+     *         the local charset.
+     *         Requires the PECL idn module.
+     *         DEFAULT: true
+     * 
* * @return string The formatted address. */ - static public function addrObject2String($ob, $filter = '') + static public function addrObject2String($ob, $opts = array()) { /* If the personal name is set, decode it. */ $ob['personal'] = isset($ob['personal']) @@ -171,10 +193,10 @@ class Horde_Mime_Address } /* Filter out unwanted addresses based on the $filter string. */ - if ($filter) { - if (!is_array($filter)) { - $filter = array($filter); - } + if (!empty($opts['filter'])) { + $filter = is_array($opts['filter']) + ? $opts['filter'] + : array($opts['filter']); foreach ($filter as $f) { if (strcasecmp($f, $ob['mailbox'] . '@' . $ob['host']) == 0) { return ''; @@ -183,7 +205,7 @@ class Horde_Mime_Address } /* Return the formatted email address. */ - return self::writeAddress($ob['mailbox'], $ob['host'], $ob['personal']); + return self::writeAddress($ob['mailbox'], $ob['host'], $ob['personal'], $opts); } /** @@ -191,14 +213,21 @@ class Horde_Mime_Address * addrObject2String(). * * @param array $addresses The array of address objects. - * @param mixed $filter A user@example.com style bare address to - * ignore. Either single string or an array of - * strings. + * @param array $opts Additional options: + *
+     * 'filter' - (mixed) A user@example.com style bare address to ignore.
+     *            Either single string or an array of strings.
+     *            DEFAULT: No filter
+     * 'idn' - (boolean) Convert IDN domain names (Punycode/RFC 3490) into
+     *         the local charset.
+     *         Requires the PECL idn module.
+     *         DEFAULT: true
+     * 
* * @return string All of the addresses in a comma-delimited string. * Returns the empty string on error/no addresses found. */ - static public function addrArray2String($addresses, $filter = '') + static public function addrArray2String($addresses, $opts = array()) { if (!is_array($addresses)) { return ''; @@ -207,7 +236,7 @@ class Horde_Mime_Address $addrList = array(); foreach ($addresses as $addr) { - $val = self::addrObject2String($addr, $filter); + $val = self::addrObject2String($addr, $opts); if (!empty($val)) { $addrList[String::lower(self::bareAddress($val))] = $val; } @@ -219,9 +248,17 @@ class Horde_Mime_Address /** * Return the list of addresses for a header object. * - * @param array $obs An array of header objects. - * @param mixed $filter A user@example.com style bare address to ignore. - * Either single string or an array of strings. + * @param array $obs An array of header objects. + * @param array $opts Additional options: + *
+     * 'filter' - (mixed) A user@example.com style bare address to ignore.
+     *            Either single string or an array of strings.
+     *            DEFAULT: No filter
+     * 'idn' - (boolean) Convert IDN domain names (Punycode/RFC 3490) into
+     *         the local charset.
+     *         Requires the PECL idn module.
+     *         DEFAULT: true
+     * 
* * @return array An array of address information. Array elements: *
@@ -233,7 +270,7 @@ class Horde_Mime_Address
      * 'personal' - (string) Personal string
      * 
*/ - static public function getAddressesFromObject($obs, $filter = '') + static public function getAddressesFromObject($obs, $opts = array()) { $ret = array(); @@ -263,7 +300,8 @@ class Horde_Mime_Address $inner = self::writeAddress($ob['mailbox'], $ob['host']); - $addr_string = self::addrObject2String($ob, $filter); + $addr_string = self::addrObject2String($ob, $opts); + if (!empty($addr_string)) { /* Generate the new object. */ $ret[] = array( @@ -404,4 +442,5 @@ class Horde_Mime_Address ? '"' . addcslashes($str, '\\"') . '"' : $str; } + } diff --git a/framework/Mime/package.xml b/framework/Mime/package.xml index 52efcb087..ff06f03ed 100644 --- a/framework/Mime/package.xml +++ b/framework/Mime/package.xml @@ -31,7 +31,8 @@ http://pear.php.net/dtd/package-2.0.xsd"> alpha LGPL - * Initial package. + * Add support for decoding IDN (RFC 3490) names (Request #5836). + * Initial package. @@ -135,6 +136,10 @@ http://pear.php.net/dtd/package-2.0.xsd"> + idn + pecl.php.net + + Auth pear.horde.org -- 2.11.0