]> git.donarmstrong.com Git - roundcube.git/blobdiff - program/steps/mail/func.inc
Imported Upstream version 0.5.3+dfsg
[roundcube.git] / program / steps / mail / func.inc
index b3c4e63b51ca7c2ee95cc7409726b853dbb8bcda..2f16e1a52348ab3400e53725c2e1bdf3f2071672 100644 (file)
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: func.inc 4509 2011-02-09 10:51:50Z thomasb $
+ $Id: func.inc 4830 2011-06-02 12:36:32Z alec $
 
 */
 
 // setup some global vars used by mail steps
 $SENT_MBOX = $RCMAIL->config->get('sent_mbox');
 $DRAFTS_MBOX = $RCMAIL->config->get('drafts_mbox');
-$SEARCH_MODS_DEFAULT = array('*' => array('subject'=>1, 'from'=>1), $SENT_MBOX => array('subject'=>1, 'to'=>1), $DRAFTS_MBOX => array('subject'=>1, 'to'=>1));
-
-// Simplified for IDN in Unicode
-//$EMAIL_ADDRESS_PATTERN = '([a-z0-9][a-z0-9\-\.\+\_]*@[a-z0-9][a-z0-9\-\.]*\\.[a-z]{2,5})';
-$EMAIL_ADDRESS_PATTERN = '([a-z0-9][a-z0-9\-\.\+\_]*@[^&@"\'.][^@&"\']*\\.[a-z]{2,5})';
+$SEARCH_MODS_DEFAULT = array(
+    '*'         => array('subject'=>1, 'from'=>1),
+    $SENT_MBOX  => array('subject'=>1, 'to'=>1),
+    $DRAFTS_MBOX => array('subject'=>1, 'to'=>1)
+);
 
 // actions that do not require imap connection here
 $NOIMAP_ACTIONS = array('addcontact', 'autocomplete', 'upload', 'display-attachment', 'remove-attachment', 'get');
@@ -575,7 +575,7 @@ function rcmail_wash_html($html, $p = array(), $cid_replaces)
     '',
     '<html>',
   );
-  $html = preg_replace($html_search, $html_replace, $html);
+  $html = preg_replace($html_search, $html_replace, trim($html));
 
   // PCRE errors handling (#1486856), should we use something like for every preg_* use?
   if ($html === null && ($preg_error = preg_last_error()) != PREG_NO_ERROR) {
@@ -607,6 +607,7 @@ function rcmail_wash_html($html, $p = array(), $cid_replaces)
       $html = '<head></head>'. $html;
     $html = substr_replace($html, '<meta http-equiv="Content-Type" content="text/html; charset='.RCMAIL_CHARSET.'" />', intval(stripos($html, '<head>')+6), 0);
   }
+
   // turn relative into absolute urls
   $html = rcmail_resolve_base($html);
 
@@ -726,71 +727,74 @@ function rcmail_plain_body($body, $flowed=false)
   $body = preg_replace_callback($replacer->mailto_pattern, array($replacer, 'mailto_callback'), $body);
 
   // split body into single lines
-  $a_lines = preg_split('/\r?\n/', $body);
+  $body = preg_split('/\r?\n/', $body);
   $quote_level = 0;
   $last = -1;
 
   // find/mark quoted lines...
-  for ($n=0, $cnt=count($a_lines); $n < $cnt; $n++) {
-    if ($a_lines[$n][0] == '>' && preg_match('/^(>+\s*)+/', $a_lines[$n], $regs)) {
+  for ($n=0, $cnt=count($body); $n < $cnt; $n++) {
+    if ($body[$n][0] == '>' && preg_match('/^(>+\s*)+/', $body[$n], $regs)) {
       $q = strlen(preg_replace('/\s/', '', $regs[0]));
-      $a_lines[$n] = substr($a_lines[$n], strlen($regs[0]));
-
-      if ($q > $quote_level)
-        $a_lines[$n] = $replacer->get_replacement($replacer->add(
-          str_repeat('<blockquote>', $q - $quote_level))) . $a_lines[$n];
-      else if ($q < $quote_level)
-        $a_lines[$n] = $replacer->get_replacement($replacer->add(
-          str_repeat('</blockquote>', $quote_level - $q))) . $a_lines[$n];
+      $body[$n] = substr($body[$n], strlen($regs[0]));
+
+      if ($q > $quote_level) {
+        $body[$n] = $replacer->get_replacement($replacer->add(
+          str_repeat('<blockquote>', $q - $quote_level))) . $body[$n];
+      }
+      else if ($q < $quote_level) {
+        $body[$n] = $replacer->get_replacement($replacer->add(
+          str_repeat('</blockquote>', $quote_level - $q))) . $body[$n];
+      }
       else if ($flowed) {
         // previous line is flowed
-        if (isset($a_lines[$last]) && $a_lines[$n]
-          && $a_lines[$last][strlen($a_lines[$last])-1] == ' ') {
+        if (isset($body[$last]) && $body[$n]
+          && $body[$last][strlen($body[$last])-1] == ' ') {
           // merge lines
-          $a_lines[$last] .= $a_lines[$n];
-          unset($a_lines[$n]);
+          $body[$last] .= $body[$n];
+          unset($body[$n]);
         }
-        else
+        else {
           $last = $n;
+        }
       }
     }
     else {
       $q = 0;
       if ($flowed) {
         // sig separator - line is fixed
-        if ($a_lines[$n] == '-- ') {
-          $last = $n;
+        if ($body[$n] == '-- ') {
+          $last = $last_sig = $n;
         }
         else {
           // remove space-stuffing
-          if ($a_lines[$n][0] == ' ')
-            $a_lines[$n] = substr($a_lines[$n], 1);
+          if ($body[$n][0] == ' ')
+            $body[$n] = substr($body[$n], 1);
 
           // previous line is flowed?
-          if (isset($a_lines[$last]) && $a_lines[$n]
-            && $a_lines[$last] != '-- '
-            && $a_lines[$last][strlen($a_lines[$last])-1] == ' '
+          if (isset($body[$last]) && $body[$n]
+            && $last != $last_sig
+            && $body[$last][strlen($body[$last])-1] == ' '
           ) {
-            $a_lines[$last] .= $a_lines[$n];
-            unset($a_lines[$n]);
+            $body[$last] .= $body[$n];
+            unset($body[$n]);
           }
           else {
             $last = $n;
           }
         }
         if ($quote_level > 0)
-          $a_lines[$last] = $replacer->get_replacement($replacer->add(
-            str_repeat('</blockquote>', $quote_level))) . $a_lines[$last];
+          $body[$last] = $replacer->get_replacement($replacer->add(
+            str_repeat('</blockquote>', $quote_level))) . $body[$last];
       }
       else if ($quote_level > 0)
-        $a_lines[$n] = $replacer->get_replacement($replacer->add(
-          str_repeat('</blockquote>', $quote_level))) . $a_lines[$n];
+        $body[$n] = $replacer->get_replacement($replacer->add(
+          str_repeat('</blockquote>', $quote_level))) . $body[$n];
     }
 
     $quote_level = $q;
   }
 
-  $body = join("\n", $a_lines);
+  $body = join("\n", $body);
 
   // quote plain text (don't use Q() here, to display entities "as is")
   $table = get_html_translation_table(HTML_SPECIALCHARS);
@@ -952,13 +956,13 @@ function rcmail_message_headers($attrib, $headers=NULL)
 function rcmail_message_full_headers($attrib, $headers=NULL)
 {
   global $OUTPUT;
-  
+
   $html = html::div(array('class' => "more-headers show-headers", 'onclick' => "return ".JS_OBJECT_NAME.".command('load-headers','',this)"), '');
   $html .= html::div(array('id' => "all-headers", 'class' => "all", 'style' => 'display:none'), html::div(array('id' => 'headers-source'), ''));
-  
+
   $OUTPUT->add_gui_object('all_headers_row', 'all-headers');
   $OUTPUT->add_gui_object('all_headers_box', 'headers-source');
-  
+
   return html::div($attrib, $html);
 }
 
@@ -1083,8 +1087,8 @@ function rcmail_resolve_base($body)
     $replacer = new rcube_base_replacer($regs[2]);
 
     // replace all relative paths
-    $body = preg_replace_callback('/(src|background|href)=(["\']?)([\.\/]+[^"\'\s]+)(\2|\s|>)/Ui', array($replacer, 'callback'), $body);
-    $body = preg_replace_callback('/(url\s*\()(["\']?)([\.\/]+[^"\'\)\s]+)(\2)\)/Ui', array($replacer, 'callback'), $body);
+    $body = preg_replace_callback('/(src|background|href)=(["\']?)([^"\'\s]+)(\2|\s|>)/Ui', array($replacer, 'callback'), $body);
+    $body = preg_replace_callback('/(url\s*\()(["\']?)([^"\'\)\s]+)(\2)\)/Ui', array($replacer, 'callback'), $body);
   }
 
   return $body;
@@ -1194,24 +1198,30 @@ function rcmail_html4inline($body, $container_id, $body_id='', &$attributes=null
  */
 function rcmail_alter_html_link($matches)
 {
-  global $RCMAIL, $EMAIL_ADDRESS_PATTERN;
+  global $RCMAIL;
+
+  // Support unicode/punycode in top-level domain part
+  $EMAIL_PATTERN = '([a-z0-9][a-z0-9\-\.\+\_]*@[^&@"\'.][^@&"\']*\\.([^\\x00-\\x40\\x5b-\\x60\\x7b-\\x7f]{2,}|xn--[a-z0-9]{2,}))';
 
   $tag = $matches[1];
   $attrib = parse_attrib_string($matches[2]);
   $end = '>';
 
+  // Remove non-printable characters in URL (#1487805)
+  $attrib['href'] = preg_replace('/[\x00-\x1F]/', '', $attrib['href']);
+
   if ($tag == 'link' && preg_match('/^https?:\/\//i', $attrib['href'])) {
     $tempurl = 'tmp-' . md5($attrib['href']) . '.css';
     $_SESSION['modcssurls'][$tempurl] = $attrib['href'];
     $attrib['href'] = $RCMAIL->url(array('task' => 'utils', 'action' => 'modcss', 'u' => $tempurl, 'c' => $GLOBALS['rcmail_html_container_id']));
     $end = ' />';
   }
-  else if (preg_match('/^mailto:'.$EMAIL_ADDRESS_PATTERN.'(\?[^"\'>]+)?/i', $attrib['href'], $mailto)) {
+  else if (preg_match('/^mailto:'.$EMAIL_PATTERN.'(\?[^"\'>]+)?/i', $attrib['href'], $mailto)) {
     $attrib['href'] = $mailto[0];
     $attrib['onclick'] = sprintf(
       "return %s.command('compose','%s',this)",
       JS_OBJECT_NAME,
-      JQ($mailto[1].$mailto[2]));
+      JQ($mailto[1].$mailto[3]));
   }
   else if (!empty($attrib['href']) && $attrib['href'][0] != '#') {
     $attrib['target'] = '_blank';