From 098ea084d624846de46648afacc0564d9f2c1959 Mon Sep 17 00:00:00 2001 From: stekkel Date: Fri, 28 Feb 2003 19:12:00 +0000 Subject: [PATCH] charset encode / decode fixes support for encoded personal names inside addresses fix for headerrequest git-svn-id: https://svn.code.sf.net/p/squirrelmail/code/trunk/squirrelmail@4564 7612ce4b-ef26-0410-bec9-ea0150e637f0 --- functions/i18n.php | 7 +- functions/imap_general.php | 379 ++++++++++++++++++++-------------- functions/imap_messages.php | 86 ++++---- functions/mailbox_display.php | 76 ++++--- functions/mime.php | 131 ++++++++---- 5 files changed, 402 insertions(+), 277 deletions(-) diff --git a/functions/i18n.php b/functions/i18n.php index cc9e3f9d..5fccb120 100644 --- a/functions/i18n.php +++ b/functions/i18n.php @@ -26,12 +26,7 @@ function charset_decode ($charset, $string) { /* All HTML special characters are 7 bit and can be replaced first */ - /* NOTE Marc Groot Koerkamp: This is the wrong place to do - htmlspecialchars, It should be done before the echo. - By doing it here we get double htmlspecialchars calls which translates - < => < => &lt; - */ - //$string = htmlspecialchars ($string); + $string = htmlspecialchars ($string); $charset = strtolower($charset); diff --git a/functions/imap_general.php b/functions/imap_general.php index 12174f51..59c4dae4 100755 --- a/functions/imap_general.php +++ b/functions/imap_general.php @@ -22,9 +22,9 @@ $sqimap_session_id = 1; function sqimap_session_id($unique_id = false) { global $data_dir, $username, $sqimap_session_id; if (!$unique_id) { - return( sprintf("A%03d", $sqimap_session_id++) ); + return( sprintf("A%03d", $sqimap_session_id++) ); } else { - return( sprintf("A%03d", $sqimap_session_id++) . ' UID' ); + return( sprintf("A%03d", $sqimap_session_id++) . ' UID' ); } } @@ -34,10 +34,10 @@ function sqimap_session_id($unique_id = false) { */ function sqimap_run_command_list ($imap_stream, $query, $handle_errors, &$response, &$message, $unique_id = false) { if ($imap_stream) { - $sid = sqimap_session_id($unique_id); - fputs ($imap_stream, $sid . ' ' . $query . "\r\n"); - $read = sqimap_read_data_list ($imap_stream, $sid, $handle_errors, $response, $message, $query ); - return $read; + $sid = sqimap_session_id($unique_id); + fputs ($imap_stream, $sid . ' ' . $query . "\r\n"); + $read = sqimap_read_data_list ($imap_stream, $sid, $handle_errors, $response, $message, $query ); + return $read; } else { global $squirrelmail_language, $color; set_up_language($squirrelmail_language); @@ -46,7 +46,7 @@ function sqimap_run_command_list ($imap_stream, $query, $handle_errors, &$respon _("ERROR : No available imapstream.") . "\n"; error_box($string,$color); - return false; + return false; } } @@ -54,9 +54,9 @@ function sqimap_run_command_list ($imap_stream, $query, $handle_errors, &$respon function sqimap_run_command ($imap_stream, $query, $handle_errors, &$response, &$message, $unique_id = false) { if ($imap_stream) { $sid = sqimap_session_id($unique_id); - fputs ($imap_stream, $sid . ' ' . $query . "\r\n"); - $read = sqimap_read_data ($imap_stream, $sid, $handle_errors, $response, $message, $query); - return $read; + fputs ($imap_stream, $sid . ' ' . $query . "\r\n"); + $read = sqimap_read_data ($imap_stream, $sid, $handle_errors, $response, $message, $query); + return $read; } else { global $squirrelmail_language, $color; set_up_language($squirrelmail_language); @@ -65,7 +65,7 @@ function sqimap_run_command ($imap_stream, $query, $handle_errors, &$response, & _("ERROR : No available imapstream.") . "\n"; error_box($string,$color); - return false; + return false; } } @@ -151,21 +151,21 @@ function sqimap_read_data_list ($imap_stream, $pre, $handle_errors, &$response, /* ignore this error from M$ exchange, it is not fatal (aka bug) */ if (strstr($message, 'command resulted in') === false) { set_up_language($squirrelmail_language); - require_once(SM_PATH . 'functions/display_messages.php'); - $string = "\n" . + require_once(SM_PATH . 'functions/display_messages.php'); + $string = "\n" . _("ERROR : Could not complete request.") . "
\n" . _("Query:") . ' ' . htmlspecialchars($query) . '
' . _("Reason Given: ") . htmlspecialchars($message) . "

\n"; - error_box($string,$color); + error_box($string,$color); exit; } } elseif ($response == 'BAD') { set_up_language($squirrelmail_language); - require_once(SM_PATH . 'functions/display_messages.php'); + require_once(SM_PATH . 'functions/display_messages.php'); $string = "\n" . _("ERROR : Bad or malformed request.") . "
\n" . @@ -173,7 +173,7 @@ function sqimap_read_data_list ($imap_stream, $pre, $handle_errors, &$response, htmlspecialchars($query) . '
' . _("Server responded: ") . htmlspecialchars($message) . "

\n"; - error_box($string,$color); + error_box($string,$color); exit; } else { @@ -217,12 +217,12 @@ function sqimap_login ($username, $password, $imap_server_address, $imap_port, $ sqgetglobalvar('onetimepad' , $onetimepad , SQ_SESSION ); } $imap_server_address = sqimap_get_user_server($imap_server_address, $username); - $host=$imap_server_address; - - if (($use_imap_tls == true) and (check_php_version(4,3)) and (extension_loaded('openssl'))) { - /* Use TLS by prefixing "tls://" to the hostname */ - $imap_server_address = 'tls://' . $imap_server_address; - } + $host=$imap_server_address; + + if (($use_imap_tls == true) and (check_php_version(4,3)) and (extension_loaded('openssl'))) { + /* Use TLS by prefixing "tls://" to the hostname */ + $imap_server_address = 'tls://' . $imap_server_address; + } $imap_stream = fsockopen ( $imap_server_address, $imap_port, $error_number, $error_string, 15); @@ -230,11 +230,11 @@ function sqimap_login ($username, $password, $imap_server_address, $imap_port, $ if (!$imap_stream) { if (!$hide) { set_up_language($squirrelmail_language, true); - require_once(SM_PATH . 'functions/display_messages.php'); - $string = sprintf (_("Error connecting to IMAP server: %s.") . - "
\r\n", $imap_server_address) . + require_once(SM_PATH . 'functions/display_messages.php'); + $string = sprintf (_("Error connecting to IMAP server: %s.") . + "
\r\n", $imap_server_address) . "$error_number : $error_string
\r\n"; - logout_error($string,$color); + logout_error($string,$color); } exit; } @@ -244,77 +244,77 @@ function sqimap_login ($username, $password, $imap_server_address, $imap_port, $ /* Decrypt the password */ $password = OneTimePadDecrypt($password, $onetimepad); - if (($imap_auth_mech == 'cram-md5') OR ($imap_auth_mech == 'digest-md5')) { + if (($imap_auth_mech == 'cram-md5') OR ($imap_auth_mech == 'digest-md5')) { // We're using some sort of authentication OTHER than plain or login - $tag=sqimap_session_id(false); - if ($imap_auth_mech == 'digest-md5') { - $query = $tag . " AUTHENTICATE DIGEST-MD5\r\n"; - } elseif ($imap_auth_mech == 'cram-md5') { - $query = $tag . " AUTHENTICATE CRAM-MD5\r\n"; - } - fputs($imap_stream,$query); - $answer=sqimap_fgets($imap_stream); - // Trim the "+ " off the front - $response=explode(" ",$answer,3); - if ($response[0] == '+') { - // Got a challenge back - $challenge=$response[1]; - if ($imap_auth_mech == 'digest-md5') { - $reply = digest_md5_response($username,$password,$challenge,'imap',$host); - } elseif ($imap_auth_mech == 'cram-md5') { - $reply = cram_md5_response($username,$password,$challenge); - } - fputs($imap_stream,$reply); - $read=sqimap_fgets($imap_stream); - if ($imap_auth_mech == 'digest-md5') { - // DIGEST-MD5 has an extra step.. - if (substr($read,0,1) == '+') { // OK so far.. - fputs($imap_stream,"\r\n"); - $read=sqimap_fgets($imap_stream); - } - } - $results=explode(" ",$read,3); - $response=$results[1]; - $message=$results[2]; + $tag=sqimap_session_id(false); + if ($imap_auth_mech == 'digest-md5') { + $query = $tag . " AUTHENTICATE DIGEST-MD5\r\n"; + } elseif ($imap_auth_mech == 'cram-md5') { + $query = $tag . " AUTHENTICATE CRAM-MD5\r\n"; + } + fputs($imap_stream,$query); + $answer=sqimap_fgets($imap_stream); + // Trim the "+ " off the front + $response=explode(" ",$answer,3); + if ($response[0] == '+') { + // Got a challenge back + $challenge=$response[1]; + if ($imap_auth_mech == 'digest-md5') { + $reply = digest_md5_response($username,$password,$challenge,'imap',$host); + } elseif ($imap_auth_mech == 'cram-md5') { + $reply = cram_md5_response($username,$password,$challenge); + } + fputs($imap_stream,$reply); + $read=sqimap_fgets($imap_stream); + if ($imap_auth_mech == 'digest-md5') { + // DIGEST-MD5 has an extra step.. + if (substr($read,0,1) == '+') { // OK so far.. + fputs($imap_stream,"\r\n"); + $read=sqimap_fgets($imap_stream); + } + } + $results=explode(" ",$read,3); + $response=$results[1]; + $message=$results[2]; } else { - // Fake the response, so the error trap at the bottom will work - $response="BAD"; - $message='IMAP server does not appear to support the authentication method selected.'; - $message .= ' Please contact your system administrator.'; + // Fake the response, so the error trap at the bottom will work + $response="BAD"; + $message='IMAP server does not appear to support the authentication method selected.'; + $message .= ' Please contact your system administrator.'; } } elseif ($imap_auth_mech == 'login') { - // Original IMAP login code + // Original IMAP login code $query = 'LOGIN "' . quoteIMAP($username) . '" "' . quoteIMAP($password) . '"'; $read = sqimap_run_command ($imap_stream, $query, false, $response, $message); } elseif ($imap_auth_mech == 'plain') { - /* Replace this with SASL PLAIN if it ever gets implemented */ - $response="BAD"; - $message='SquirrelMail does not support SASL PLAIN yet. Rerun conf.pl and use login instead.'; - } else { - $response="BAD"; - $message="Internal SquirrelMail error - unknown IMAP authentication method chosen. Please contact the developers."; - } + /* Replace this with SASL PLAIN if it ever gets implemented */ + $response="BAD"; + $message='SquirrelMail does not support SASL PLAIN yet. Rerun conf.pl and use login instead.'; + } else { + $response="BAD"; + $message="Internal SquirrelMail error - unknown IMAP authentication method chosen. Please contact the developers."; + } - /* If the connection was not successful, lets see why */ + /* If the connection was not successful, lets see why */ if ($response != 'OK') { if (!$hide) { if ($response != 'NO') { /* "BAD" and anything else gets reported here. */ - $message = htmlspecialchars($message); + $message = htmlspecialchars($message); set_up_language($squirrelmail_language, true); - require_once(SM_PATH . 'functions/display_messages.php'); + require_once(SM_PATH . 'functions/display_messages.php'); if ($response == 'BAD') { $string = sprintf (_("Bad request: %s")."
\r\n", $message); } else { $string = sprintf (_("Unknown error: %s") . "
\n", $message); } if (isset($read) && is_array($read)) { - $string .= '
' . _("Read data:") . "
\n"; + $string .= '
' . _("Read data:") . "
\n"; foreach ($read as $line) { $string .= htmlspecialchars($line) . "
\n"; } } - error_box($string,$color); + error_box($string,$color); exit; } else { /* @@ -330,7 +330,7 @@ function sqimap_login ($username, $password, $imap_server_address, $imap_port, $ set_up_language($squirrelmail_language, true); include_once(SM_PATH . 'functions/display_messages.php' ); - sqsession_destroy(); + sqsession_destroy(); logout_error( _("Unknown user or password incorrect.") ); exit; } @@ -365,11 +365,11 @@ function sqimap_capability($imap_stream, $capability='') { } } if ($capability) { - if (isset($sqimap_capabilities[$capability])) { - return $sqimap_capabilities[$capability]; - } else { - return false; - } + if (isset($sqimap_capabilities[$capability])) { + return $sqimap_capabilities[$capability]; + } else { + return false; + } } return $sqimap_capabilities; } @@ -431,63 +431,126 @@ function sqimap_get_num_messages ($imap_stream, $mailbox) { return false; //"BUG! Couldn't get number of messages in $mailbox!"; } - -/* Returns a displayable email address. - * Luke Ehresman - * "Luke Ehresman" - * - * lehresma@css.tayloru.edu (Luke Ehresman) - * lehresma@css.tayloru.edu - * becomes: lehresma@css.tayloru.edu - */ -function sqimap_find_email ($string) { - if (ereg("<([^>]+)>", $string, $regs)) { - $string = $regs[1]; - } else if (ereg("([^ ]+@[^ ]+)", $string, $regs)) { - $string = $regs[1]; +function parseAddress($address, $max=0, $addr_ar = array(), $group = '', $host='') { + $pos = 0; + $j = strlen($address); + $personal = ''; + $addr = ''; + $comment = ''; + if ($max && $max = count($addr_ar)) { + return $addr_ar; } - return trim($string); -} - - -/* - * Takes the From: field and creates a displayable name. - * Luke Ehresman - * "Luke Ehresman" - * lkehresman@yahoo.com (Luke Ehresman) - * becomes: Luke Ehresman - * - * becomes: lkehresman@yahoo.com - */ -function sqimap_find_displayable_name ($string) { - $string = trim($string); - - if ( ereg('^(.+)<.*>', $string, $regs) ) { - $orig_string = $string; - $string = str_replace ('"', '', $regs[1] ); - if (trim($string) == '') { - $string = sqimap_find_email($orig_string); + while ($pos < $j) { + if ($max && $max = count($addr_ar)) { + return $addr_ar; } - if( $string == '' || $string == ' ' ){ - $string = ' '; + $char = $address{$pos}; + switch ($char) { + case '=': + if (preg_match('/^(=\?([^?]*)\?(Q|B)\?([^?]*)\?=)(.*)/Ui',substr($address,$pos),$reg)) { + $personal = $reg[1]; + $pos += strlen($personal); + } + ++$pos; + break; + case '"': /* get the personal name */ + ++$pos; + if ($address{$pos} == '"') { + ++$pos; + } else { + $personal_start = $personal_end = $pos; + while ($pos < $j) { + $personal_end = strpos($address,'"',$pos); + if (($personal_end-2)>0 && (substr($address,$personal_end-2,2) === '\\"' || + substr($address,$personal_end-2,2) === '\\\\')) { + $pos = $personal_end+1; + } else { + $personal = substr($address,$personal_start,$personal_end-$personal_start); + break; + } + } + if ($personal_end) { /* prohibit endless loops due to very wrong addresses */ + $pos = $personal_end+1; + } else { + $pos = $j; + } + } + break; + case '<': /* get email address */ + $addr_start = $pos; + $addr_end = strpos($address,'>',$addr_start); + $addr = substr($address,$addr_start+1,$addr_end-$addr_start-1); + $pos = $addr_end+1; + break; + case '(': /* rip off comments */ + $addr_start = $pos; + $pos = strpos($address,')'); + if ($pos !== false) { + $comment = substr($address, $addr_start+1,($pos-$addr_start-1)); + $address_start = substr($address, 0, $addr_start); + $address_end = substr($address, $pos + 1); + $address = $address_start . $address_end; + } + $j = strlen($address); + $pos = $addr_start + 1; + break; + case ',': /* we reached a delimiter */ + if ($addr == '') { + $addr = substr($address, 0, $pos); + } else if ($personal == '') { + $personal = trim(substr($address, 0, $addr_start)); + } + if (!$personal && $comment) $personal = $comment; + if ($personal) $personal = decodeHeader($personal); + $addr_ar[] = array($addr,$personal); + $address = trim(substr($address, $pos+1)); + $j = strlen($address); + $pos = 0; + $personal = ''; + $addr = ''; + break; + case ':': /* process the group addresses */ + /* group marker */ + $group = substr($address, 0, $pos); + $address = substr($address, $pos+1); + $result = parseAddress($address, $max, $addr_ar, $group); + $addr_ar = $result[0]; + $pos = $result[1]; + $address = substr($address, $pos++); + $j = strlen($address); + $group = ''; + break; + case ';': + if ($group) { + $address = substr($address, 0, $pos - 1); + } + ++$pos; + break; + default: + ++$pos; + break; } } - elseif ( ereg('\((.*)\)', $string, $regs) ) { - if( ( $regs[1] == '' ) || ( $regs[1] == ' ' ) ){ - if ( ereg('^(.+) \(', $string, $regs) ) { - $string = ereg_replace( ' \(\)$', '', $string ); - } else { - $string = ' '; - } - } else { - $string = $regs[1]; - } + if ($addr == '') { + $addr = substr($address, 0, $pos); + } else if ($personal == '') { + $personal = trim(substr($address, 0, $addr_start)); } - else { - $string = str_replace ('"', '', sqimap_find_email($string)); + if (!$personal && $comment) $personal = $comment; + $email = $addr; + if ($group && $addr == '') { /* no addresses found in group */ + $personal = $group; + $addr_ar[] = array('',$personal); + return (array($addr_ar,$pos+1 )); + } elseif ($group) { + $addr_ar[] = array($addr,$personal); + return (array($addr_ar,$pos+1 )); + } else { + if ($personal || $addr) { + $addr_ar[] = array($addr, $personal); + } } - - return trim($string); + return ($addr_ar); } /* @@ -516,14 +579,14 @@ function sqimap_status_messages ($imap_stream, $mailbox) { $regs = array(false,false); while (isset($read_ary[$i])) { if (preg_match('/UNSEEN\s+([0-9]+)/i', $read_ary[$i], $regs)) { - $unseen = $regs[1]; - } + $unseen = $regs[1]; + } if (preg_match('/MESSAGES\s+([0-9]+)/i', $read_ary[$i], $regs)) { - $messages = $regs[1]; - } + $messages = $regs[1]; + } if (preg_match('/RECENT\s+([0-9]+)/i', $read_ary[$i], $regs)) { - $recent = $regs[1]; - } + $recent = $regs[1]; + } $i++; } return array('MESSAGES' => $messages, 'UNSEEN'=>$unseen, 'RECENT' => $recent); @@ -545,29 +608,29 @@ function sqimap_append_done ($imap_stream, $folder='') { if (preg_match("/(.*)(BAD|NO)(.*)$/", $tmp, $regs)) { set_up_language($squirrelmail_language); require_once(SM_PATH . 'functions/display_messages.php'); - $reason = $regs[3]; - if ($regs[2] == 'NO') { - $string = "\n" . - _("ERROR : Could not append message to") ." $folder." . - "
\n" . - _("Server responded: ") . - $reason . "
\n"; - if (preg_match("/(.*)(quota)(.*)$/i", $reason, $regs)) { - $string .= _("Solution: ") . - _("Remove unneccessary messages from your folder and start with your Trash folder.") - ."
\n"; - } - $string .= "
\n"; - error_box($string,$color); - } else { + $reason = $regs[3]; + if ($regs[2] == 'NO') { + $string = "\n" . + _("ERROR : Could not append message to") ." $folder." . + "
\n" . + _("Server responded: ") . + $reason . "
\n"; + if (preg_match("/(.*)(quota)(.*)$/i", $reason, $regs)) { + $string .= _("Solution: ") . + _("Remove unneccessary messages from your folder and start with your Trash folder.") + ."
\n"; + } + $string .= "
\n"; + error_box($string,$color); + } else { $string = "\n" . - _("ERROR : Bad or malformed request.") . - "
\n" . - _("Server responded: ") . - $tmp . "

\n"; - error_box($string,$color); + _("ERROR : Bad or malformed request.") . + "

\n" . + _("Server responded: ") . + $tmp . "

\n"; + error_box($string,$color); exit; - } + } } } diff --git a/functions/imap_messages.php b/functions/imap_messages.php index 3cf506b8..c8a98781 100755 --- a/functions/imap_messages.php +++ b/functions/imap_messages.php @@ -66,15 +66,8 @@ function sqimap_toggle_flag($imap_stream, $id, $flag, $set, $handle_errors) { $read = sqimap_run_command ($imap_stream, "STORE $msgs_id ".$set_string."FLAGS ($flag)", $handle_errors, $response, $message, $uid_support); } - -/* Returns some general header information -- FROM, DATE, and SUBJECT */ -class small_header { - var $from = '', $subject = '', $date = '', $to = '', - $priority = 0, $message_id = 0, $cc = '', $uid = ''; -} - function sqimap_get_small_header ($imap_stream, $id, $sent) { - $res = sqimap_get_small_header_list($imap_stream, array($id), $sent); + $res = sqimap_get_small_header_list($imap_stream, $id, $sent); return $res[0]; } @@ -217,10 +210,10 @@ function sqimap_get_php_sort_order ($imap_stream, $mbxresponse) { if ($uid_support) { if (isset($mbxresponse['UIDNEXT']) && $mbxresponse['UIDNEXT']) { - $uidnext = $mbxresponse['UIDNEXT']-1; - } else { - $uidnext = '*'; - } + $uidnext = $mbxresponse['UIDNEXT']-1; + } else { + $uidnext = '*'; + } $uid_query = "$sid SEARCH UID 1:$uidnext\r\n"; fputs($imap_stream, $uid_query); $uids = sqimap_read_data($imap_stream, $sid, true ,$response, $message); @@ -431,6 +424,7 @@ function sqimap_get_small_header_list ($imap_stream, $msg_list) { $sid = sqimap_session_id($uid_support); $maxmsg = sizeof($msg_list); + $msgs_str = sqimap_message_list_squisher($msg_list); $messages = array(); $read_list = array(); @@ -445,9 +439,9 @@ function sqimap_get_small_header_list ($imap_stream, $msg_list) { $internaldate = getPref($data_dir, $username, 'internal_date_sort'); if ($internaldate) { - $query = "$sid FETCH $msgs_str (FLAGS UID RFC822.SIZE INTERNALDATE BODY.PEEK[HEADER.FIELDS (Date To From Cc Subject X-Priority Content-Type)])\r\n"; + $query = "$sid FETCH $msgs_str (FLAGS UID RFC822.SIZE INTERNALDATE BODY.PEEK[HEADER.FIELDS (Date To Cc From Subject X-Priority Content-Type)])\r\n"; } else { - $query = "$sid FETCH $msgs_str (FLAGS UID RFC822.SIZE BODY.PEEK[HEADER.FIELDS (Date To From Cc Subject X-Priority Content-Type)])\r\n"; + $query = "$sid FETCH $msgs_str (FLAGS UID RFC822.SIZE BODY.PEEK[HEADER.FIELDS (Date To Cc From Subject X-Priority Content-Type)])\r\n"; } fputs ($imap_stream, $query); $readin_list = sqimap_read_data_list($imap_stream, $sid, false, $response, $message); @@ -585,22 +579,22 @@ function sqimap_get_small_header_list ($imap_stream, $msg_list) { if (preg_match ($regpattern, $read_part, $regs)) { switch ($id) { case 1: - $to = $regs[1]; + $to = trim($regs[1]); break; case 2: - $from = $regs[1]; + $from = trim($regs[1]); break; case 3: $priority = $regs[1]; break; case 4: - $cc = $regs[1]; + $cc = trim($regs[1]); break; case 5: $date = $regs[1]; break; case 6: - $subject = htmlspecialchars(trim($regs[1])); + $subject = trim($regs[1]); if ($subject == "") { $subject = _("(no subject)"); } @@ -641,11 +635,13 @@ function sqimap_get_small_header_list ($imap_stream, $msg_list) { $messages[$msgi]['TIME_STAMP'] = getTimeStamp($tmpdate); $messages[$msgi]['DATE_STRING'] = getDateString($messages[$msgi]['TIME_STAMP']); - $messages[$msgi]['FROM'] = decodeHeader($from); - $messages[$msgi]['SUBJECT'] = decodeHeader($subject); - $messages[$msgi]['TO'] = decodeHeader($to); + $messages[$msgi]['FROM'] = parseAddress($from); + $messages[$msgi]['SUBJECT'] = $subject; +// if (handleAsSent($mailbox)) { + $messages[$msgi]['TO'] = parseAddress($to); +// } $messages[$msgi]['PRIORITY'] = $priority; - $messages[$msgi]['CC'] = $cc; + $messages[$msgi]['CC'] = parseAddress($cc); $messages[$msgi]['SIZE'] = $size; $messages[$msgi]['TYPE0'] = $type[0]; $messages[$msgi]['FLAG_DELETED'] = $flag_deleted; @@ -655,7 +651,13 @@ function sqimap_get_small_header_list ($imap_stream, $msg_list) { /* non server sort stuff */ if (!$allow_server_sort) { - $messages[$msgi]['FROM-SORT'] = strtolower(sqimap_find_displayable_name(decodeHeader($from))); + $from = parseAddress($from); + if ($from[0][1]) { + $from = decodeHeader($from[0][1]); + } else { + $from = $from[0][0]; + } + $messages[$msgi]['FROM-SORT'] = $from; $subject_sort = strtolower(decodeHeader($subject)); if (preg_match("/^(vedr|sv|re|aw):\s*(.*)$/si", $subject_sort, $matches)){ $messages[$msgi]['SUBJECT-SORT'] = $matches[2]; @@ -682,12 +684,12 @@ function sqimap_get_headerfield($imap_stream, $field) { foreach ($readin_list as $r) { $r = implode('',$r); /* first we unfold the header */ - $r = str_replace(array("\r\n\t","\r\n\s"),array('',''),$r); - /* - * now we can make a new header array with each element representing - * a headerline - */ - $r = explode("\r\n" , $r); + $r = str_replace(array("\r\n\t","\r\n\s"),array('',''),$r); + /* + * now we can make a new header array with each element representing + * a headerline + */ + $r = explode("\r\n" , $r); if (!$uid_support) { if (!preg_match("/^\\*\s+([0-9]+)\s+FETCH/iAU",$r[0], $regs)) { set_up_language($squirrelmail_language); @@ -708,12 +710,12 @@ function sqimap_get_headerfield($imap_stream, $field) { _("Unknown response from IMAP server: ") . ' 1.' . $r[0] . "
\n"; } else { - $id = $regs[2]; + $id = $regs[2]; } } - $field = $r[1]; - $field = substr($field,strlen($field)+2); - $result[] = array($id,$field); + $field = $r[1]; + $field = substr($field,strlen($field)+2); + $result[] = array($id,$field); } return $result; } @@ -770,19 +772,6 @@ function sqimap_get_ent_header ($imap_stream, $id, $mailbox, $ent) { return $header; } - -/* Wrapper function that returns entity headers for use by decodeMime */ -/* -function sqimap_get_entity_header ($imap_stream, &$read, &$type0, &$type1, &$bound, &$encoding, &$charset, &$filename) { - $header = sqimap_get_header($imap_stream, $read); - $type0 = $header["TYPE0"]; - $type1 = $header["TYPE1"]; - $bound = $header["BOUNDARY"]; - $encoding = $header["ENCODING"]; - $charset = $header["CHARSET"]; - $filename = $header["FILENAME"]; -} - /* function to get the mime headers */ function sqimap_get_mime_ent_header ($imap_stream, $id, $mailbox, $ent) { global $uid_support; @@ -793,9 +782,4 @@ function sqimap_get_mime_ent_header ($imap_stream, $id, $mailbox, $ent) { return $header; } -/* Returns the body of a message. */ -function sqimap_get_message_body ($imap_stream, &$header) { -// return decodeMime($imap_stream, $header->id); -} - ?> diff --git a/functions/mailbox_display.php b/functions/mailbox_display.php index d0b67efa..79954364 100644 --- a/functions/mailbox_display.php +++ b/functions/mailbox_display.php @@ -20,6 +20,20 @@ require_once(SM_PATH . 'functions/imap_mailbox.php'); /* Default value for page_selector_max. */ define('PG_SEL_MAX', 10); +function elapsed($start) +{ + $end = microtime(); + list($start2, $start1) = explode(" ", $start); + list($end2, $end1) = explode(" ", $end); + $diff1 = $end1 - $start1; + $diff2 = $end2 - $start2; + if( $diff2 < 0 ){ + $diff1 -= 1; + $diff2 += 1.0; + } + return $diff2 + $diff1; +} + function printMessageInfo($imapConnection, $t, $not_last=true, $key, $mailbox, $start_msg, $where, $what) { global $checkall, @@ -58,25 +72,29 @@ function printMessageInfo($imapConnection, $t, $not_last=true, $key, $mailbox, if (handleAsSent($mailbox)) { $msg['FROM'] = $msg['TO']; + } /* * This is done in case you're looking into Sent folders, * because you can have multiple receivers. */ - $senderNames = explode(',', $msg['FROM']); - $senderName = ''; - if (sizeof($senderNames)){ - foreach ($senderNames as $senderNames_part) { + + $senderNames = $msg['FROM']; + $senderName = ''; + if (sizeof($senderNames)){ + foreach ($senderNames as $senderNames_part) { if ($senderName != '') { $senderName .= ', '; } - $senderName .= sqimap_find_displayable_name($senderNames_part); - } - } - } else { - $senderName = sqimap_find_displayable_name($msg['FROM']); - } + if ($senderNames_part[1]) { + $senderName .= decodeHeader($senderNames_part[1]); + } else { + $senderName .= htmlspecialchars($senderNames_part[0]); + } + } + } + - $subject = processSubject($msg['SUBJECT'], $indent_array[$msg['ID']]); + $subject = processSubject(decodeHeader($msg['SUBJECT']), $indent_array[$msg['ID']]); echo html_tag( 'tr','','','','VALIGN="top"') . "\n"; @@ -124,10 +142,19 @@ function printMessageInfo($imapConnection, $t, $not_last=true, $key, $mailbox, $high_val = strtolower($message_highlight_list_part['value']); $match_type = strtoupper($message_highlight_list_part['match_type']); if ($match_type == 'TO_CC') { - if (strstr('^^' . strtolower($msg['TO']), $high_val) || - strstr('^^' . strtolower($msg['CC']), $high_val)) { - $hlt_color = $message_highlight_list_part['color']; - continue; + foreach ($msg['TO'] as $address) { + if (strstr('^^' . strtolower($address[0]), $high_val) || + strstr('^^' . strtolower($address[1]), $high_val)) { + $hlt_color = $message_highlight_list_part['color']; + continue; + } + } + foreach ($msg['CC'] as $address) { + if( strstr('^^' . strtolower($address[0]), $high_val) || + strstr('^^' . strtolower($address[1]), $high_val)) { + $hlt_color = $message_highlight_list_part['color']; + continue; + } } } else { if (strstr('^^' . strtolower($msg[$match_type]), $high_val)) { @@ -155,7 +182,7 @@ function printMessageInfo($imapConnection, $t, $not_last=true, $key, $mailbox, break; case 2: /* from */ echo html_tag( 'td', - $italic . $bold . $flag . $fontstr . htmlentities($senderName) . + $italic . $bold . $flag . $fontstr . $senderName . $fontstr_end . $flag_end . $bold_end . $italic_end, 'left', $hlt_color ); @@ -182,7 +209,7 @@ function printMessageInfo($imapConnection, $t, $not_last=true, $key, $mailbox, $td_str .= ''; + $t = elapsed($start); + echo("elapsed time = $t seconds\n"); } function calc_msort($msgs, $sort) { diff --git a/functions/mime.php b/functions/mime.php index 48866d6d..ca43a355 100644 --- a/functions/mime.php +++ b/functions/mime.php @@ -271,7 +271,6 @@ function translateText(&$body, $wrap_at, $charset) { sqWordWrap($line, $wrap_at); } $line = charset_decode($charset, $line); - $line = htmlspecialchars($line); $line = str_replace("\t", ' ', $line); parseUrl ($line); @@ -308,7 +307,6 @@ function translateText(&$body, $wrap_at, $charset) { $body = '
' . implode("\n", $body_ary) . '
'; } - /* This returns a parsed string called $body. That string can then * be displayed as the actual message in the HTML. It contains * everything needed, including HTML Tags, Attachments at the @@ -409,7 +407,7 @@ function formatAttachments($message, $exclude_id, $mailbox, $id) { if ($type0 =='message' && $type1 == 'rfc822') { $default_page = '../src/read_body.php'; $rfc822_header = $att->rfc822_header; - $filename = decodeHeader($rfc822_header->subject); + $filename = $rfc822_header->subject; if (trim( $filename ) == '') { $filename = 'untitled-[' . $ent . ']' ; } @@ -419,16 +417,16 @@ function formatAttachments($message, $exclude_id, $mailbox, $id) { } else { $from_name = _("Unknown sender"); } - $from_name = decodeHeader(htmlspecialchars($from_name)); + $from_name = decodeHeader(($from_name)); $description = $from_name; } else { $default_page = '../src/download.php'; if (is_object($header->disposition)) { - $filename = decodeHeader($header->disposition->getProperty('filename')); + $filename = $header->disposition->getProperty('filename'); if (trim($filename) == '') { $name = decodeHeader($header->disposition->getProperty('name')); if (trim($name) == '') { - $name = decodeHeader($header->getParameter('name')); + $name = $header->getParameter('name'); if(trim($name) == '') { if (trim( $header->id ) == '') { $filename = 'untitled-[' . $ent . ']' ; @@ -443,7 +441,7 @@ function formatAttachments($message, $exclude_id, $mailbox, $id) { } } } else { - $filename = decodeHeader($header->getParameter('name')); + $filename = $header->getParameter('name'); if (!trim($filename)) { if (trim( $header->id ) == '') { $filename = 'untitled-[' . $ent . ']' ; @@ -453,7 +451,7 @@ function formatAttachments($message, $exclude_id, $mailbox, $id) { } } if ($header->description) { - $description = htmlspecialchars($header->description); + $description = decodeHeader($header->description); } else { $description = ''; } @@ -488,7 +486,7 @@ function formatAttachments($message, $exclude_id, $mailbox, $id) { $defaultlink = $hookresults[6]; $attachments .= '' . - '
'.htmlspecialchars($display_filename).' ' . + ''.decodeHeader($display_filename).' ' . '' . show_readable_size($header->size) . '  ' . "[ $type0/$type1 ] " . @@ -545,7 +543,7 @@ function decodeBody($body, $encoding) { * RFC1522 (MIME Part Two: Message Header Extensions for Non-ASCII Text). * Patched by Christian Schmidt 23/03/2002 */ -function decodeHeader ($string, $utfencode=true) { +function decodeHeader ($string, $utfencode=true,$htmlsave=true) { global $languages, $squirrelmail_language; if (is_array($string)) { $string = implode("\n", $string); @@ -557,33 +555,54 @@ function decodeHeader ($string, $utfencode=true) { } $i = 0; - while (preg_match('/^(.{' . $i . '})(.*)=\?([^?]*)\?(Q|B)\?([^?]*)\?=/Ui', - $string, $res)) { - $prefix = $res[1]; - /* Ignore white-space between consecutive encoded-words. */ - if (strspn($res[2], " \t") != strlen($res[2])) { - $prefix .= $res[2]; - } - - if (ucfirst($res[4]) == 'B') { - $replace = base64_decode($res[5]); - $replace = charset_decode($res[3],$replace); - - } else { - $replace = str_replace('_', ' ', $res[5]); - $replace = preg_replace('/=([0-9a-f]{2})/ie', 'chr(hexdec("\1"))', + $aString = explode(' ',$string); + foreach ($aString as $chunk) { + $encoded = false; + $aString[$i] = ''; + while (preg_match('/^(.*)=\?([^?]*)\?(Q|B)\?([^?]*)\?=(.*)$/Ui',$chunk,$res)) { + $aString[$i] .= $res[1]; + $encoding = ucfirst($res[3]); + switch ($encoding) + { + case 'B': + $replace = base64_decode($res[4]); + $aString[$i] .= charset_decode($res[2],$replace); + break; + case 'Q': + + $replace = str_replace('_', ' ', $res[4]); + $replace = preg_replace('/=([0-9a-f]{2})/ie', 'chr(hexdec("\1"))', $replace); - /* Only encode into entities by default. Some places - * don't need the encoding, like the compose form. - */ - if ($utfencode) { - $replace = charset_decode($res[3], $replace); + /* Only encode into entities by default. Some places + * don't need the encoding, like the compose form. + */ + if ($utfencode) { + $replace = charset_decode($res[2], $replace); + } else { + if ($htmlsave) { + $replace = htmlspecialchars($res[4]); + } + } + $aString[$i] .= $replace; + break; + default: + break; } + $chunk = $res[5]; + $encoded = true; + } + if (!$encoded && $htmlsave) { + $aString[$i] = htmlspecialchars($chunk); + } else { + $aString[$i] .= $chunk; } - $string = $prefix . $replace . substr($string, strlen($res[0])); - $i = strlen($prefix) + strlen($replace); + ++$i; + } + if (!$htmlsave) { + return implode(' ',$aString); + } else { + return implode(' ',$aString); } - return $string; } /* @@ -602,27 +621,67 @@ function encodeHeader ($string) { // Encode only if the string contains 8-bit characters or =? $j = strlen($string); $l = strstr($string, '=?'); // Must be encoded ? + $max_l = 75 - strlen($default_charset) - 7; + $aRet = array(); $ret = ''; + $cur_l = 0; for($i = 0; $i < $j; ++$i) { switch($string{$i}) { case '=': + $cur_l+=3; + if ($cur_l > $max_l) { + $aRet[] = "=?$default_charset?Q?$ret?="; + $cur_l = 3; + $ret = ''; + } $ret .= '=3D'; break; case '?': + $cur_l+=3; + if ($cur_l > $max_l) { + $aRet[] = "=?$default_charset?Q?$ret?="; + $cur_l = 3; + $ret = ''; + } $ret .= '=3F'; break; case '_': + $cur_l+=3; + if ($cur_l > $max_l) { + $aRet[] = "=?$default_charset?Q?$ret?="; + $cur_l = 3; + $ret = ''; + } $ret .= '=5F'; break; case ' ': + $cur_l++; + if ($cur_l > $max_l) { + $aRet[] = "=?$default_charset?Q?$ret?="; + $cur_l = 1; + $ret = ''; + } $ret .= '_'; break; default: $k = ord($string{$i}); if ($k > 126) { - $ret .= sprintf("=%02X", $k); + $s = sprintf("=%02X", $k); + $cur_l += strlen($s); + if ($cur_l > $max_l) { + $aRet[] = "=?$default_charset?Q?$ret?="; + $cur_l = strlen($s); + $ret = ''; + } + $ret .= $s; $l = TRUE; } else { + $cur_l++; + if ($cur_l > $max_l) { + $aRet[] = "=?$default_charset?Q?$ret?="; + $cur_l = 1; + $ret = ''; + } $ret .= $string{$i}; } break; @@ -630,7 +689,7 @@ function encodeHeader ($string) { } if ($l) { - $string = "=?$default_charset?Q?$ret?="; + $string = implode('',$aRet) . "=?$default_charset?Q?$ret?="; } return $string; @@ -1230,7 +1289,7 @@ function sq_fixstyle($message, $id, $content){ $content = preg_replace("|url\(([\'\"])\s*https*:.*?([\'\"])\)|si", "url(\\1$secremoveimg\\2)", $content); } - + /** * Fix urls that refer to cid: */ -- 2.25.1