From b48d9bf5d412a6f56f3f9ba4bad141ddfe175727 Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Mon, 07 Sep 2009 08:51:21 -0400
Subject: [PATCH] - Use faster/secure mt_rand() (#1486094)

---
 program/steps/mail/func.inc |  104 ++++++++++++++++++++++++++++++++--------------------
 1 files changed, 64 insertions(+), 40 deletions(-)

diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index 154fd7e..ed36e84 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -19,9 +19,7 @@
 
 */
 
-require_once('include/rcube_smtp.inc');
-
-$EMAIL_ADDRESS_PATTERN = '([a-z0-9][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-z0-9][a-z0-9\-\.]*\\.[a-z]{2,5})';
 
 // actions that do not require imap connection
 $NOIMAP_ACTIONS = array('spell', 'addcontact', 'autocomplete', 'upload', 'display-attachment', 'remove-attachment');
@@ -95,6 +93,8 @@
     $OUTPUT->set_env('read_when_deleted', true);
   if ($CONFIG['skip_deleted'])
     $OUTPUT->set_env('skip_deleted', true);
+  if ($CONFIG['display_next'])
+    $OUTPUT->set_env('display_next', true);
 	  
   if ($CONFIG['trash_mbox'])
     $OUTPUT->set_env('trash_mailbox', $CONFIG['trash_mbox']);
@@ -244,7 +244,6 @@
   if (!sizeof($a_headers))
     $OUTPUT->show_message('nomessagesfound', 'notice');
 
-
   $a_js_message_arr = array();
 
   // create row for each message
@@ -301,7 +300,6 @@
     
     $out .= sprintf("<td class=\"icon\">%s</td>\n", $message_icon ? sprintf($image_tag, $skin_path, $message_icon, '') : '');
 
-
     $IMAP->set_charset(!empty($header->charset) ? $header->charset : $CONFIG['default_charset']);
   
     // format each col
@@ -315,7 +313,7 @@
         $uid_param = $mbox==$CONFIG['drafts_mbox'] ? '_draft_uid' : '_uid';
         $cont = abbreviate_string(trim($IMAP->decode_header($header->$col)), 160);
         if (empty($cont)) $cont = rcube_label('nosubject');
-        $cont = sprintf('<a href="%s" onclick="return rcube_event.cancel(event)">%s</a>', Q(rcmail_url($action, array($uid_param=>$header->uid, '_mbox'=>$mbox))), Q($cont));
+        $cont = $OUTPUT->browser->ie ? Q($cont) : sprintf('<a href="%s" onclick="return rcube_event.cancel(event)">%s</a>', Q(rcmail_url($action, array($uid_param=>$header->uid, '_mbox'=>$mbox))), Q($cont));
         }
       else if ($col=='flag')
         $cont = $flagged_icon ? sprintf($image_tag, $skin_path, $flagged_icon, '') : '';
@@ -432,9 +430,9 @@
         {
         $action = $mbox==$CONFIG['drafts_mbox'] ? 'compose' : 'show';
         $uid_param = $mbox==$CONFIG['drafts_mbox'] ? '_draft_uid' : '_uid';
-        $cont = abbreviate_string(trim($IMAP->decode_header($header->$col)), 160);
+	$cont = abbreviate_string(trim($IMAP->decode_header($header->$col)), 160);
         if (!$cont) $cont = rcube_label('nosubject');
-        $cont = sprintf('<a href="%s" onclick="return rcube_event.cancel(event)">%s</a>', Q(rcmail_url($action, array($uid_param=>$header->uid, '_mbox'=>$mbox))), Q($cont));
+        $cont = $browser->ie ? Q($cont) : sprintf('<a href="%s" onclick="return rcube_event.cancel(event)">%s</a>', Q(rcmail_url($action, array($uid_param=>$header->uid, '_mbox'=>$mbox))), Q($cont));
         }
       else if ($col=='size')
         $cont = show_bytes($header->$col);
@@ -456,7 +454,7 @@
       $a_msg_flags['forwarded'] = 1;
     if ($header->flagged)
       $a_msg_flags['flagged'] = 1;
-    
+
     $OUTPUT->command('add_message_row',
       $header->uid,
       $a_msg_cols,
@@ -672,40 +670,38 @@
   global $REMOTE_OBJECTS;
   
   $p += array('safe' => false, 'inline_html' => true);
-  
+
   // special replacements (not properly handled by washtml class)
   $html_search = array(
     '/(<\/nobr>)(\s+)(<nobr>)/i',	// space(s) between <NOBR>
-    '/(<[\/]*st1:[^>]+>)/i',		// Microsoft's Smart Tags <ST1>
-    '/<\/?rte_text>/i',			// Rich Text Editor tags (#1485647)
     '/<title>.*<\/title>/i',		// PHP bug #32547 workaround: remove title tag
-    '/<html[^>]*>/im',			// malformed html: remove html tags (#1485139)
-    '/<\/html>/i',			// malformed html: remove html tags (#1485139)
     '/^(\0\0\xFE\xFF|\xFF\xFE\0\0|\xFE\xFF|\xFF\xFE|\xEF\xBB\xBF)/',	// byte-order mark (only outlook?)
+    '/<html\s[^>]+>/i',			// washtml/DOMDocument cannot handle xml namespaces
   );
   $html_replace = array(
     '\\1'.' &nbsp; '.'\\3',
     '',
     '',
-    '',
-    '',
-    '',
-    '',
+    '<html>',
   );
   $html = preg_replace($html_search, $html_replace, $html);
 
-  // charset was converted to UTF-8 in rcube_imap::get_message_part() -> change charset specification in HTML accordingly
-  $charset_pattern = '/(\s+content=[\'"]?\w+\/\w+;\s*charset)=([a-z0-9-_]+)/i';
-  if (preg_match($charset_pattern, $html)) {
-    $html = preg_replace($charset_pattern, '\\1='.RCMAIL_CHARSET, $html);
+  // fix (unknown/malformed) HTML tags before "wash"
+  $html = preg_replace_callback('/(<[\/!]*)([^ >]+)/', 'rcmail_html_tag_callback', $html);
+
+  // charset was converted to UTF-8 in rcube_imap::get_message_part(),
+  // -> change charset specification in HTML accordingly
+  $charset_pattern = '(<meta\s+[^>]*)(content=[\'"]?\w+\/\w+;\s*charset)=([a-z0-9-_]+)';
+  if (preg_match("/$charset_pattern/Ui", $html)) {
+    $html = preg_replace("/$charset_pattern/i", '\\1\\2='.RCMAIL_CHARSET, $html);
   }
   else {
-    // add head for malformed messages, washtml cannot work without that
+    // add meta content-type to malformed messages, washtml cannot work without that
     if (!preg_match('/<head[^>]*>(.*)<\/head>/Uims', $html))
       $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);
+    $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);
 
@@ -730,9 +726,8 @@
   $washer = new washtml($wash_opts);
   $washer->add_callback('form', 'rcmail_washtml_callback');
 
-  if ($p['safe']) {  // allow CSS styles, will be sanitized by rcmail_washtml_callback()
-    $washer->add_callback('style', 'rcmail_washtml_callback');
-  }
+  // allow CSS styles, will be sanitized by rcmail_washtml_callback()
+  $washer->add_callback('style', 'rcmail_washtml_callback');
     
   $html = $washer->wash($html);
   $REMOTE_OBJECTS = $washer->extlinks;
@@ -808,7 +803,7 @@
         if ($q > $quote_level)
           $q_lines[$n]['quote'] = $q - $quote_level;
         else if ($q < $quote_level)
-          $eq_lines[$n]['endquote'] = $quote_level - $q;
+          $q_lines[$n]['endquote'] = $quote_level - $q;
       }
       else if ($quote_level > 0)
         $q_lines[$n]['endquote'] = $quote_level;
@@ -819,7 +814,14 @@
     // quote plain text
     $body = Q(join("\n", $a_lines), 'replace', false);
 
-    // ... colorize quoted lines
+    // colorize signature
+    if (($sp = strrpos($body, '-- ')) !== false)
+      if (($sp == 0 || $body[$sp-1] == "\n") && $body[$sp+3] == "\n") {
+	$body = substr($body, 0, max(0, $sp))
+	    .'<span class="sig">'.substr($body, $sp).'</span>';
+      }
+
+    // colorize quoted lines
     $a_lines = preg_split('/\n/', $body);
     foreach ($q_lines as $i => $q)
       if ($q['quote'])
@@ -861,7 +863,7 @@
       
     case 'style':
       // decode all escaped entities and reduce to ascii strings
-      $stripped = preg_replace('/[^a-zA-Z\(:]/', '', rcmail_xss_entitiy_decode($content));
+      $stripped = preg_replace('/[^a-zA-Z\(:]/', '', rcmail_xss_entity_decode($content));
       
       // now check for evil strings like expression, behavior or url()
       if (!preg_match('/expression|behavior|url\(|import/', $stripped)) {
@@ -874,6 +876,22 @@
   }
   
   return $out;
+}
+
+
+/**
+ * Callback function for HTML tags fixing
+ */
+function rcmail_html_tag_callback($matches)
+{
+  $tagname = $matches[2];
+
+  $tagname = preg_replace(array(
+    '/:.*$/',		// Microsoft's Smart Tags <st1:xxxx>
+    '/[^a-z0-9_-]/i',	// forbidden characters
+    ), '', $tagname);
+
+  return $matches[1].$tagname;
 }
 
 
@@ -897,7 +915,7 @@
   // get associative array of headers object
   if (!$headers)
     $headers = is_object($MESSAGE->headers) ? get_object_vars($MESSAGE->headers) : $MESSAGE->headers;
-    
+
   // show these headers
   $standard_headers = array('subject', 'from', 'to', 'cc', 'bcc', 'replyto', 'date');
   $output_headers = array();
@@ -980,7 +998,7 @@
       {
       if ($part->type == 'headers')
         $out .= rcmail_message_headers(sizeof($header_attrib) ? $header_attrib : NULL, $part->headers);
-      else if ($part->type == 'content')
+      else if ($part->type == 'content' && $part->size)
         {
         if (empty($part->ctype_parameters) || empty($part->ctype_parameters['charset']))
           $part->ctype_parameters['charset'] = $MESSAGE->headers->charset;
@@ -1295,7 +1313,7 @@
 /**
  * Send the given message compose object using the configured method
  */
-function rcmail_deliver_message(&$message, $from, $mailto)
+function rcmail_deliver_message(&$message, $from, $mailto, &$smtp_error)
 {
   global $CONFIG, $RCMAIL;
 
@@ -1319,8 +1337,12 @@
     unset($message->_headers['Bcc']);
 
     // send message
-    $smtp_response = array();
-    $sent = smtp_mail($from, $a_recipients, ($foo = $message->txtHeaders($send_headers, true)), $msg_body, $smtp_response);
+    if (!is_object($RCMAIL->smtp))
+      $RCMAIL->smtp_init(true);
+     
+    $sent = $RCMAIL->smtp->send_mail($from, $a_recipients, ($foo = $message->txtHeaders($send_headers, true)), $msg_body);
+    $smtp_response = $RCMAIL->smtp->get_response();
+    $smtp_error = $RCMAIL->smtp->get_error();
 
     // log error
     if (!$sent)
@@ -1373,7 +1395,7 @@
 }
 
 
-function rcmail_send_mdn($uid)
+function rcmail_send_mdn($uid, &$smtp_error)
 {
   global $RCMAIL, $IMAP;
 
@@ -1403,7 +1425,7 @@
       'From' => $sender,
       'To'   => $message->headers->mdn_to,
       'Subject' => rcube_label('receiptread') . ': ' . $message->subject,
-      'Message-ID' => sprintf('<%s@%s>', md5(uniqid('rcmail'.rand(),true)), $RCMAIL->config->mail_domain($_SESSION['imap_host'])),
+      'Message-ID' => sprintf('<%s@%s>', md5(uniqid('rcmail'.mt_rand(),true)), $RCMAIL->config->mail_domain($_SESSION['imap_host'])),
       'X-Sender' => $identity['email'],
       'Content-Type' => 'multipart/report; report-type=disposition-notification',
     );
@@ -1431,7 +1453,7 @@
     $compose->setTXTBody(rc_wordwrap($body, 75, "\r\n"));
     $compose->addAttachment($report, 'message/disposition-notification', 'MDNPart2.txt', false, '7bit', 'inline');
 
-    $sent = rcmail_deliver_message($compose, $identity['email'], $mailto);
+    $sent = rcmail_deliver_message($compose, $identity['email'], $mailto, $smtp_error);
 
     if ($sent)
     {
@@ -1446,7 +1468,7 @@
 
 function rcmail_search_filter($attrib)
 {
-  global $OUTPUT;
+  global $OUTPUT, $CONFIG;
 
   if (!strlen($attrib['id']))
     $attrib['id'] = 'rcmlistfilter';
@@ -1466,6 +1488,8 @@
   $select_filter->add(rcube_label('unread'), 'UNSEEN');
   $select_filter->add(rcube_label('flagged'), 'FLAGGED');
   $select_filter->add(rcube_label('unanswered'), 'UNANSWERED');
+  if (!$CONFIG['skip_deleted'])
+    $select_filter->add(rcube_label('deleted'), 'DELETED');
 
   $out = $select_filter->show($_SESSION['search_filter']);
 

--
Gitblit v1.9.1