From e8d5bdc84ecfdf6fe5008655215a258bbdf0c521 Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Thu, 03 Feb 2011 08:58:07 -0500
Subject: [PATCH] - Fix IDNA support when IDN/INTL modules are in use (#1487742)

---
 program/include/rcube_smtp.php           |    7 ++-
 CHANGELOG                                |    1 
 program/include/main.inc                 |   33 ++++++++++++++++
 program/include/rcube_ldap.php           |    2 
 program/steps/mail/compose.inc           |    8 ++--
 program/steps/addressbook/save.inc       |    2 
 program/steps/settings/save_identity.inc |   14 +++---
 program/steps/mail/sendmail.inc          |    6 +-
 program/include/rcube_config.php         |    2 
 program/steps/settings/edit_identity.inc |    6 +-
 program/include/rcube_shared.inc         |    2 
 program/steps/addressbook/import.inc     |    2 
 program/include/rcmail.php               |    4 +-
 program/steps/mail/func.inc              |    6 +-
 program/steps/settings/func.inc          |    2 
 program/include/rcube_template.php       |    2 
 program/steps/mail/addcontact.inc        |    2 
 17 files changed, 68 insertions(+), 33 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index c827c0b..af40cf6 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
 CHANGELOG Roundcube Webmail
 ===========================
 
+- Fix IDNA support when IDN/INTL modules are in use (#1487742)
 - Fix handling of invalid HTML comments in messages (#1487759)
 - Fix parsing FETCH response for very long headers (#1487753)
 - Fix add/remove columns in message list when message_sort_order isn't set (#1487751)
diff --git a/program/include/main.inc b/program/include/main.inc
index 7f49456..697b3ff 100644
--- a/program/include/main.inc
+++ b/program/include/main.inc
@@ -1891,6 +1891,39 @@
   return false;
 }
 
+/*
+ * Idn_to_ascii wrapper.
+ * Intl/Idn modules version of this function doesn't work with e-mail address
+ */
+function rcube_idn_to_ascii($str)
+{
+  return rcube_idn_convert($str, true);
+}
+
+/*
+ * Idn_to_ascii wrapper.
+ * Intl/Idn modules version of this function doesn't work with e-mail address
+ */
+function rcube_idn_to_utf8($str)
+{
+  return rcube_idn_convert($str, false);
+}
+
+function rcube_idn_convert($input, $is_utf=false)
+{
+  if ($at = strpos($input, '@')) {
+    $user   = substr($input, 0, $at);
+    $domain = substr($input, $at+1);
+  }
+  else {
+    $domain = $input;
+  }
+
+  $domain = $is_utf ? idn_to_ascii($domain) : idn_to_utf8($domain);
+
+  return $at ? $user . '@' . $domain : $domain;
+}
+
 
 /**
  * Helper class to turn relative urls into absolute ones
diff --git a/program/include/rcmail.php b/program/include/rcmail.php
index c2ca51a..8c80fe2 100644
--- a/program/include/rcmail.php
+++ b/program/include/rcmail.php
@@ -699,12 +699,12 @@
 
     // Here we need IDNA ASCII
     // Only rcube_contacts class is using domain names in Unicode
-    $host = idn_to_ascii($host);
+    $host = rcube_idn_to_ascii($host);
     if (strpos($username, '@')) {
       // lowercase domain name
       list($local, $domain) = explode('@', $username);
       $username = $local . '@' . mb_strtolower($domain);
-      $username = idn_to_ascii($username);
+      $username = rcube_idn_to_ascii($username);
     }
 
     // user already registered -> overwrite username
diff --git a/program/include/rcube_config.php b/program/include/rcube_config.php
index 058927d..81b664a 100644
--- a/program/include/rcube_config.php
+++ b/program/include/rcube_config.php
@@ -287,7 +287,7 @@
             $domain = rcube_parse_host($this->prop['mail_domain']);
 
         if ($encode)
-            $domain = idn_to_ascii($domain);
+            $domain = rcube_idn_to_ascii($domain);
 
         return $domain;
     }
diff --git a/program/include/rcube_ldap.php b/program/include/rcube_ldap.php
index 4fe74e3..5db9220 100644
--- a/program/include/rcube_ldap.php
+++ b/program/include/rcube_ldap.php
@@ -138,7 +138,7 @@
 
     foreach ($this->prop['hosts'] as $host)
     {
-      $host = idn_to_ascii(rcube_parse_host($host));
+      $host = rcube_idn_to_ascii(rcube_parse_host($host));
       $this->_debug("C: Connect [$host".($this->prop['port'] ? ':'.$this->prop['port'] : '')."]");
 
       if ($lc = @ldap_connect($host, $this->prop['port']))
diff --git a/program/include/rcube_shared.inc b/program/include/rcube_shared.inc
index 83eefd6..2aa1100 100644
--- a/program/include/rcube_shared.inc
+++ b/program/include/rcube_shared.inc
@@ -719,7 +719,7 @@
             $loaded = true;
         }
 
-        if ($idn && $domain && preg_match('/(^|@|\.)xn--/i', $domain)) {
+        if ($idn && $domain && preg_match('/(^|\.)xn--/i', $domain)) {
             try {
                 $domain = $idn->decode($domain);
             }
diff --git a/program/include/rcube_smtp.php b/program/include/rcube_smtp.php
index 3eaf052..654c7ef 100644
--- a/program/include/rcube_smtp.php
+++ b/program/include/rcube_smtp.php
@@ -101,7 +101,7 @@
       $helo_host = 'localhost';
 
     // IDNA Support
-    $smtp_host = idn_to_ascii($smtp_host);
+    $smtp_host = rcube_idn_to_ascii($smtp_host);
 
     $this->conn = new Net_SMTP($smtp_host, $smtp_port, $helo_host);
 
@@ -132,8 +132,9 @@
     if ($smtp_user && $smtp_pass)
     {
       // IDNA Support
-      if (strpos($smtp_user, '@'))
-        $smtp_user = idn_to_ascii($smtp_user);
+      if (strpos($smtp_user, '@')) {
+        $smtp_user = rcube_idn_to_ascii($smtp_user);
+      }
 
       $result = $this->conn->auth($smtp_user, $smtp_pass, $smtp_auth_type, $use_tls, $smtp_authz);
 
diff --git a/program/include/rcube_template.php b/program/include/rcube_template.php
index 1d1a95b..2102aaa 100755
--- a/program/include/rcube_template.php
+++ b/program/include/rcube_template.php
@@ -1034,7 +1034,7 @@
             $username = $this->app->user->get_username();
         }
 
-        return idn_to_utf8($username);
+        return rcube_idn_to_utf8($username);
     }
 
 
diff --git a/program/steps/addressbook/import.inc b/program/steps/addressbook/import.inc
index 532afdb..af6f67d 100644
--- a/program/steps/addressbook/import.inc
+++ b/program/steps/addressbook/import.inc
@@ -136,7 +136,7 @@
       }
 
       // We're using UTF8 internally
-      $email = idn_to_utf8($email);
+      $email = rcube_idn_to_utf8($email);
       
       if (!$replace) {
         // compare e-mail address
diff --git a/program/steps/addressbook/save.inc b/program/steps/addressbook/save.inc
index 4eb24fe..934db4c 100644
--- a/program/steps/addressbook/save.inc
+++ b/program/steps/addressbook/save.inc
@@ -142,7 +142,7 @@
 // Validity checks
 foreach ($CONTACTS->get_col_values('email', $a_record, true) as $email) {
   if (strlen($email)) {
-    $_email = idn_to_ascii($email);
+    $_email = rcube_idn_to_ascii($email);
     if (!check_email($_email, false)) {
       $OUTPUT->show_message('emailformaterror', 'warning', array('email' => $email));
       rcmail_overwrite_action($return_action);
diff --git a/program/steps/mail/addcontact.inc b/program/steps/mail/addcontact.inc
index 2808698..ba9a44a 100644
--- a/program/steps/mail/addcontact.inc
+++ b/program/steps/mail/addcontact.inc
@@ -46,7 +46,7 @@
       $OUTPUT->send();
     }
 
-    $contact['email'] = idn_to_utf8($contact['email']);
+    $contact['email'] = rcube_idn_to_utf8($contact['email']);
 
     // use email address part for name
     if (empty($contact['name']) || $contact['name'] == $contact['email'])
diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc
index b2cd584..d894b97 100644
--- a/program/steps/mail/compose.inc
+++ b/program/steps/mail/compose.inc
@@ -321,7 +321,7 @@
         if (empty($addr_part['mailto']))
           continue;
 
-        $mailto = idn_to_utf8($addr_part['mailto']);
+        $mailto = rcube_idn_to_utf8($addr_part['mailto']);
 
         if (!in_array($mailto, $sa_recipients)
             && (!$MESSAGE->compose_from
@@ -360,7 +360,7 @@
       if (empty($addr_part['mailto']))
         continue;
 
-      $mailto = idn_to_utf8($addr_part['mailto']);
+      $mailto = rcube_idn_to_utf8($addr_part['mailto']);
 
       if ($addr_part['name'] && $addr_part['mailto'] != $addr_part['name'])
         $string = format_email_recipient($mailto, $addr_part['name']);
@@ -437,7 +437,7 @@
     // create SELECT element
     foreach ($user_identities as $sql_arr)
     {
-      $email = mb_strtolower(idn_to_utf8($sql_arr['email']));
+      $email = mb_strtolower(rcube_idn_to_utf8($sql_arr['email']));
       $identity_id = $sql_arr['identity_id'];
       $select_from->add(format_email_recipient($email, $sql_arr['name']), $identity_id);
 
@@ -734,7 +734,7 @@
   // build reply prefix
   $from = array_pop($RCMAIL->imap->decode_address_list($MESSAGE->get_header('from'), 1, false));
   $prefix = sprintf("On %s, %s wrote:",
-    $MESSAGE->headers->date, $from['name'] ? $from['name'] : idn_to_utf8($from['mailto']));
+    $MESSAGE->headers->date, $from['name'] ? $from['name'] : rcube_idn_to_utf8($from['mailto']));
 
   if (!$bodyIsHtml) {
     $body = preg_replace('/\r?\n/', "\n", $body);
diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index 9abfef7..b1b5d91 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -1250,10 +1250,10 @@
 
     // IDNA ASCII to Unicode
     if ($name == $mailto)
-      $name = idn_to_utf8($name);
+      $name = rcube_idn_to_utf8($name);
     if ($string == $mailto)
-      $string = idn_to_utf8($string);
-    $mailto = idn_to_utf8($mailto);
+      $string = rcube_idn_to_utf8($string);
+    $mailto = rcube_idn_to_utf8($mailto);
 
     if ($PRINT_MODE) {
       $out .= sprintf('%s &lt;%s&gt;', Q($name), $mailto);
diff --git a/program/steps/mail/sendmail.inc b/program/steps/mail/sendmail.inc
index 74b8c00..118e9ed 100644
--- a/program/steps/mail/sendmail.inc
+++ b/program/steps/mail/sendmail.inc
@@ -153,11 +153,11 @@
     $item = trim($item);
     // address in brackets without name (do nothing)
     if (preg_match('/^<\S+@\S+>$/', $item)) {
-      $item = idn_to_ascii($item);
+      $item = rcube_idn_to_ascii($item);
       $result[] = $item;
     // address without brackets and without name (add brackets)
     } else if (preg_match('/^\S+@\S+$/', $item)) {
-      $item = idn_to_ascii($item);
+      $item = rcube_idn_to_ascii($item);
       $result[] = '<'.$item.'>';
     // address with name (handle name)
     } else if (preg_match('/\S+@\S+>*$/', $item, $matches)) {
@@ -168,7 +168,7 @@
           && preg_match('/[\(\)\<\>\\\.\[\]@,;:"]/', $name)) {
             $name = '"'.addcslashes($name, '"').'"';
       }
-      $address = idn_to_ascii($address);
+      $address = rcube_idn_to_ascii($address);
       if (!preg_match('/^<\S+@\S+>$/', $address))
         $address = '<'.$address.'>';
 
diff --git a/program/steps/settings/edit_identity.inc b/program/steps/settings/edit_identity.inc
index 9bf8dca..71bd349 100644
--- a/program/steps/settings/edit_identity.inc
+++ b/program/steps/settings/edit_identity.inc
@@ -94,9 +94,9 @@
     $form['addressing']['content']['email']['class'] = 'disabled';
   }
 
-  $IDENTITY_RECORD['email']    = idn_to_utf8($IDENTITY_RECORD['email']);
-  $IDENTITY_RECORD['reply-to'] = idn_to_utf8($IDENTITY_RECORD['reply-to']);
-  $IDENTITY_RECORD['bcc']      = idn_to_utf8($IDENTITY_RECORD['bcc']);
+  $IDENTITY_RECORD['email']    = rcube_idn_to_utf8($IDENTITY_RECORD['email']);
+  $IDENTITY_RECORD['reply-to'] = rcube_idn_to_utf8($IDENTITY_RECORD['reply-to']);
+  $IDENTITY_RECORD['bcc']      = rcube_idn_to_utf8($IDENTITY_RECORD['bcc']);
 
   // Allow plugins to modify identity form content
   $plugin = $RCMAIL->plugins->exec_hook('identity_form', array(
diff --git a/program/steps/settings/func.inc b/program/steps/settings/func.inc
index 7f4e282..271ee40 100644
--- a/program/steps/settings/func.inc
+++ b/program/steps/settings/func.inc
@@ -72,7 +72,7 @@
   // get identities list and define 'mail' column
   $list = $USER->list_identities();
   foreach ($list as $idx => $row)
-    $list[$idx]['mail'] = trim($row['name'] . ' <' . idn_to_utf8($row['email']) .'>');
+    $list[$idx]['mail'] = trim($row['name'] . ' <' . rcube_idn_to_utf8($row['email']) .'>');
 
   // get all identites from DB and define list of cols to be displayed
   $plugin = $RCMAIL->plugins->exec_hook('identities_list', array(
diff --git a/program/steps/settings/save_identity.inc b/program/steps/settings/save_identity.inc
index e3bbce9..f0d25f3 100644
--- a/program/steps/settings/save_identity.inc
+++ b/program/steps/settings/save_identity.inc
@@ -59,7 +59,7 @@
 // Validate e-mail addresses
 foreach (array('email', 'reply-to', 'bcc') as $item) {
   if ($email = $save_data[$item]) {
-    $ascii_email = idn_to_ascii($email);
+    $ascii_email = rcube_idn_to_ascii($email);
     if (!check_email($ascii_email, false)) {
       // show error message
       $OUTPUT->show_message('emailformaterror', 'error', array('email' => $email), false);
@@ -77,11 +77,11 @@
   $save_data = $plugin['record'];
 
   if ($save_data['email'])
-    $save_data['email'] = idn_to_ascii($save_data['email']);
+    $save_data['email'] = rcube_idn_to_ascii($save_data['email']);
   if ($save_data['bcc'])
-    $save_data['bcc'] = idn_to_ascii($save_data['bcc']);
+    $save_data['bcc'] = rcube_idn_to_ascii($save_data['bcc']);
   if ($save_data['reply-to'])
-    $save_data['reply-to'] = idn_to_ascii($save_data['reply-to']);
+    $save_data['reply-to'] = rcube_idn_to_ascii($save_data['reply-to']);
 
   if (!$plugin['abort'])
     $updated = $USER->update_identity($iid, $save_data);
@@ -116,9 +116,9 @@
   $plugin = $RCMAIL->plugins->exec_hook('identity_create', array('record' => $save_data));
   $save_data = $plugin['record'];
 
-  $save_data['email']    = idn_to_ascii($save_data['email']);
-  $save_data['bcc']      = idn_to_ascii($save_data['bcc']);
-  $save_data['reply-to'] = idn_to_ascii($save_data['reply-to']);
+  $save_data['email']    = rcube_idn_to_ascii($save_data['email']);
+  $save_data['bcc']      = rcube_idn_to_ascii($save_data['bcc']);
+  $save_data['reply-to'] = rcube_idn_to_ascii($save_data['reply-to']);
 
   if (!$plugin['abort'])
     $insert_id = $save_data['email'] ? $USER->insert_identity($save_data) : null;

--
Gitblit v1.9.1