From 81de00c0eba6c2f4aebcfdd24124be99a3996871 Mon Sep 17 00:00:00 2001 From: stekkel Date: Sat, 11 Feb 2006 15:14:31 +0000 Subject: [PATCH] Fix for #1093360. The fix also includes the move from manual generated error messages in imap_general to the central error handler. In order to catch non fatal error message in compose.php I had to collect the error messages array before the header redirect and write them to the session. In read_body.php, compose.php and right_main.php I add the error messages to the error handler again and clean up the delayed error messages array. I also modified the error handler in order to display the page_header in case it wasn't displayed yet. git-svn-id: https://svn.code.sf.net/p/squirrelmail/code/trunk/squirrelmail@10705 7612ce4b-ef26-0410-bec9-ea0150e637f0 --- class/error.class.php | 25 +++++++++ functions/imap_general.php | 112 +++++++++++++++++++++++++------------ functions/page_header.php | 5 +- include/errors.php | 24 ++++++++ src/compose.php | 15 +++++ src/read_body.php | 11 ++-- src/right_main.php | 6 +- 7 files changed, 157 insertions(+), 41 deletions(-) diff --git a/class/error.class.php b/class/error.class.php index 7eba7966..aabea017 100644 --- a/class/error.class.php +++ b/class/error.class.php @@ -43,6 +43,7 @@ class ErrorHandler { $this->TemplateName = $sTemplateFile; $this->Template =& $oTemplate; $this->aErrors = array(); + $this->header_sent = false; } /** @@ -53,6 +54,26 @@ class ErrorHandler { $this->TemplateFile = $sTemplateFile; } + /** + * Sets if the page header is already sent + * @since 1.5.1 + */ + function HeaderSent() { + $this->header_sent = true; + } + + /** + * Sets the error template + * @since 1.5.1 + */ + function AssignDelayedErrors(&$aDelayedErrors) { + $aErrors = array_merge($this->aErrors,$aDelayedErrors); + $this->aErrors = $aErrors; + $this->Template->assign('aErrors',$this->aErrors); + $aDelayedErrors = false; + } + + /** * Custom Error handler (set with set_error_handler() ) * @private @@ -172,6 +193,10 @@ class ErrorHandler { // Show the error immediate in case of fatal errors if ($iType == SQM_ERROR) { + if (!$this->header_sent) { + // replace this with template that can be assigned + displayHtmlHeader(_("Error"),'',false); + } $this->DisplayErrors(); exit(_("Terminating SquirrelMail due to a fatal error")); } diff --git a/functions/imap_general.php b/functions/imap_general.php index 14672a6b..47e35bfb 100755 --- a/functions/imap_general.php +++ b/functions/imap_general.php @@ -1146,7 +1146,7 @@ function sqimap_status_messages ($imap_stream, $mailbox, if (!empty($messages)) { $hook_status['MESSAGES']=$messages; } if (!empty($unseen)) { $hook_status['UNSEEN']=$unseen; } if (!empty($recent)) { $hook_status['RECENT']=$recent; } - if (!empty($hook_status)) { + if (!empty($hook_status)) { $hook_status['MAILBOX']=$mailbox; $hook_status['CALLER']='sqimap_status_messages'; do_hook_function('folder_status',$hook_status); @@ -1160,61 +1160,103 @@ function sqimap_status_messages ($imap_stream, $mailbox, * @param stream $imap_stream * @param string $sent_folder * @param $length + * @return string $sid */ -function sqimap_append ($imap_stream, $sent_folder, $length) { - fputs ($imap_stream, sqimap_session_id() . ' APPEND ' . sqimap_encode_mailbox_name($sent_folder) . " (\\Seen) {".$length."}\r\n"); +function sqimap_append ($imap_stream, $sMailbox, $length) { + $sid = sqimap_session_id(); + $query = $sid . ' APPEND ' . sqimap_encode_mailbox_name($sMailbox) . " (\\Seen) {".$length."}"; + fputs ($imap_stream, "$query\r\n"); $tmp = fgets ($imap_stream, 1024); - sqimap_append_checkresponse($tmp, $sent_folder); + sqimap_append_checkresponse($tmp, $sMailbox,$sid, $query); + return $sid; } /** * @param stream imap_stream * @param string $folder (since 1.3.2) */ -function sqimap_append_done ($imap_stream, $folder='') { +function sqimap_append_done ($imap_stream, $sMailbox='') { fputs ($imap_stream, "\r\n"); $tmp = fgets ($imap_stream, 1024); - sqimap_append_checkresponse($tmp, $folder); + while (!sqimap_append_checkresponse($tmp, $sMailbox)) { + $tmp = fgets ($imap_stream, 1024); + } } /** * Displays error messages, if there are errors in responses to * commands issues by sqimap_append() and sqimap_append_done() functions. * @param string $response - * @param string $folder + * @param string $sMailbox + * @return bool $bDone * @since 1.5.1 and 1.4.5 */ -function sqimap_append_checkresponse($response, $folder) { - // TODO use error handler, see how sort and thread errors are handled and see errors.php - if (preg_match("/(.*)(BAD|NO)(.*)$/", $response, $regs)) { - global $squirrelmail_language, $color; - set_up_language($squirrelmail_language); - require_once(SM_PATH . 'functions/display_messages.php'); +function sqimap_append_checkresponse($response, $sMailbox, $sid='', $query='') { + global $color; + // static vars to keep them available when sqimap_append_done calls this function. + static $imapquery, $imapsid; - $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:") . ' ' . - $reason . "

\n"; - error_box($string,$color); - exit; + $bDone = false; + + if ($query) { + $imapquery = $query; + } + if ($sid) { + $imapsid = $sid; + } + if ($response{0} == '+') { + // continuation request triggerd by sqimap_append() + $bDone = true; + } else { + $i = strpos($response, ' '); + $sRsp = substr($response,0,$i); + $sMsg = substr($response,$i+1); + $aExtra = array('MAILBOX' => $sMailbox); + switch ($sRsp) { + case '*': //untagged response + $i = strpos($sMsg, ' '); + $sRsp = strtoupper(substr($sMsg,0,$i)); + $sMsg = substr($sMsg,$i+1); + if ($sRsp == 'NO' || $sRsp == 'BAD') { + // for the moment disabled. Enable after 1.5.1 release. + // Notices could give valueable information about the mailbox + // sqm_trigger_imap_error('SQM_IMAP_APPEND_NOTICE',$imapquery,$sRsp,$sMsg); + } + $bDone = false; + case $imapsid: + // A001 OK message + // $imapsid$sRsp$sMsg + $bDone = true; + $i = strpos($sMsg, ' '); + $sRsp = strtoupper(substr($sMsg,0,$i)); + $sMsg = substr($sMsg,$i+1); + switch ($sRsp) { + case 'NO': + if (preg_match("/(.*)(quota)(.*)$/i", $sMsg, $aMatch)) { + sqm_trigger_imap_error('SQM_IMAP_APPEND_QUOTA_ERROR',$imapquery,$sRsp,$sMsg,$aExtra); + } else { + sqm_trigger_imap_error('SQM_IMAP_APPEND_ERROR',$imapquery,$sRsp,$sMsg,$aExtra); + } + break; + case 'BAD': + sqm_trigger_imap_error('SQM_IMAP_ERROR',$imapquery,$sRsp,$sMsg,$aExtra); + break; + case 'BYE': + sqm_trigger_imap_error('SQM_IMAP_BYE',$imapquery,$sRsp,$sMsg,$aExtra); + break; + case 'OK': + break; + default: + break; + } + break; + default: + // should be false because of the unexpected response but i'm not sure if + // that will cause an endless loop in sqimap_append_done + $bDone = true; } } + return $bDone; } /** diff --git a/functions/page_header.php b/functions/page_header.php index 25c1ff30..93b7d8b3 100644 --- a/functions/page_header.php +++ b/functions/page_header.php @@ -34,7 +34,7 @@ include_once(SM_PATH . 'class/template/template.class.php'); * @return void */ function displayHtmlHeader( $title = 'SquirrelMail', $xtra = '', $do_hook = TRUE, $frames = FALSE ) { - global $squirrelmail_language, $sTplDir; + global $squirrelmail_language, $sTplDir, $oErroHandler; if ( !sqgetGlobalVar('base_uri', $base_uri, SQ_SESSION) ) { global $base_uri; @@ -112,6 +112,9 @@ ECHO; /* this is used to check elsewhere whether we should call this function */ $pageheader_sent = TRUE; + if (isset($oErrorHandler)) { + $oErrorHander->HeaderSent(); + } } /** diff --git a/include/errors.php b/include/errors.php index 972d40d9..2c639192 100644 --- a/include/errors.php +++ b/include/errors.php @@ -49,6 +49,21 @@ $aErrors['SQM_IMAP_BADCHARSET'] = array( 'tip' => _("Run \"configure\", choose option 4 (General options) and set option 12 (Allow server charset search) to false) or choose option 10 (Language settings) and set option 2 (Default charset) to a charset supported by your IMAP server.") ); +$aErrors['SQM_IMAP_APPEND_QUOTA_ERROR'] = array( + 'level' => E_USER_NOTICE, + 'category' => SQM_ERROR_IMAP, + 'message' => _( "Out of quota error."), + 'link' => '', + 'tip' => _("Remove unneccessary messages from your folder and start with your Trash folder.") +); + +$aErrors['SQM_IMAP_APPEND_ERROR'] = array( + 'level' => E_USER_NOTICE, + 'category' => SQM_ERROR_IMAP, + 'message' => _( "An error occured when SquirrelMail appended a message to the mailbox as listed in this message."), + 'link' => '' +); + $aErrors['SQM_IMAP_ERROR'] = array( 'level' => E_USER_ERROR, 'category' => SQM_ERROR_IMAP, @@ -56,6 +71,15 @@ $aErrors['SQM_IMAP_ERROR'] = array( _("Please contact your system administrator and report this error."), 'link' => '' ); + +$aErrors['SQM_IMAP_BYE'] = array( + 'level' => E_USER_ERROR, + 'category' => SQM_ERROR_IMAP, + 'message' => _( "IMAP server closed the connection.") . "\n" . + _("Please contact your system administrator and report this error."), + 'link' => '' +); + //$aError['SQM_FS'] // Filesystem related errors ?> \ No newline at end of file diff --git a/src/compose.php b/src/compose.php index e0ef1378..1678bfd7 100644 --- a/src/compose.php +++ b/src/compose.php @@ -48,6 +48,11 @@ sqgetGlobalVar('delimiter', $delimiter, SQ_SESSION); sqgetGlobalVar('composesession', $composesession, SQ_SESSION); sqgetGlobalVar('compose_messages', $compose_messages, SQ_SESSION); +sqgetGlobalVar('delayed_errors', $delayed_errors, SQ_SESSION); +if (is_array($delayed_errors)) { + $oErrorHandler->AssignDelayedErrors($delayed_errors); + sqsession_unregister("delayed_errors"); +} /** SESSION/POST/GET VARS */ sqgetGlobalVar('session',$session); @@ -386,6 +391,9 @@ if ($draft) { } sqimap_logout($imap_stream); } + if (count($oErrorHandler->aErrors)) { + sqsession_register($oErrorHandler->aErrors,"delayed_errors"); + } session_write_close(); if ($compose_new_win == '1') { if ( !isset($pageheader_sent) || !$pageheader_sent ) { @@ -461,6 +469,7 @@ if ($send) { $composeMessage=$compose_messages[$session]; $Result = deliverMessage($composeMessage); + do_hook('compose_send_after', $Result, $composeMessage); if (! $Result) { showInputForm($session); @@ -481,6 +490,12 @@ if ($send) { } sqimap_logout($imap_stream); } + /* + * Store the error array in the session because they will be lost on a redirect + */ + if (count($oErrorHandler->aErrors)) { + sqsession_register($oErrorHandler->aErrors,"delayed_errors"); + } session_write_close(); if ($compose_new_win == '1') { if ( !isset($pageheader_sent) || !$pageheader_sent ) { diff --git a/src/read_body.php b/src/read_body.php index 77f4aafd..2e1f9987 100644 --- a/src/read_body.php +++ b/src/read_body.php @@ -323,11 +323,11 @@ function SendMDN ( $mailbox, $passed_id, $sender, $message, $imapConnection) { } else { unset ($deliver); if (sqimap_mailbox_exists ($imapConnection, $sent_folder)) { - sqimap_append ($imapConnection, $sent_folder, $length); + $sid = sqimap_append ($imapConnection, $sent_folder, $length); require_once(SM_PATH . 'class/deliver/Deliver_IMAP.class.php'); $imap_deliver = new Deliver_IMAP(); $imap_deliver->mail($composeMessage, $imapConnection); - sqimap_append_done ($imapConnection); + sqimap_append_done ($imapConnection, $sent_folder); unset ($imap_deliver); } } @@ -807,7 +807,11 @@ sqgetGlobalVar('lastTargetMailbox', $lastTargetMailbox, SQ_SESSION); if (!sqgetGlobalVar('messages', $messages, SQ_SESSION) ) { $messages = array(); } - +sqgetGlobalVar('delayed_errors', $delayed_errors, SQ_SESSION); +if (is_array($delayed_errors)) { + $oErrorHandler->AssignDelayedErrors($delayed_errors); + sqsession_unregister("delayed_errors"); +} /** GET VARS */ sqgetGlobalVar('sendreceipt', $sendreceipt, SQ_GET); if (!sqgetGlobalVar('where', $where, SQ_GET) ) { @@ -967,7 +971,6 @@ if (isset($aMailbox['MSG_HEADERS'][$passed_id]['MESSAGE_OBJECT'])) { $message->is_seen = true; $aMailbox['MSG_HEADERS'][$passed_id]['MESSAGE_OBJECT'] = $message; } - if (isset($passed_ent_id) && $passed_ent_id) { $message = $message->getEntity($passed_ent_id); if ($message->type0 != 'message' && $message->type1 != 'rfc822') { diff --git a/src/right_main.php b/src/right_main.php index 88841c6a..ccbaf6d4 100644 --- a/src/right_main.php +++ b/src/right_main.php @@ -40,7 +40,11 @@ sqgetGlobalVar('username', $username, SQ_SESSION); sqgetGlobalVar('onetimepad',$onetimepad, SQ_SESSION); sqgetGlobalVar('delimiter', $delimiter, SQ_SESSION); sqgetGlobalVar('base_uri', $base_uri, SQ_SESSION); - +sqgetGlobalVar('delayed_errors', $delayed_errors, SQ_SESSION); +if (is_array($delayed_errors)) { + $oErrorHandler->AssignDelayedErrors($delayed_errors); + sqsession_unregister("delayed_errors"); +} sqgetGlobalVar('mailbox', $mailbox); sqgetGlobalVar('lastTargetMailbox', $lastTargetMailbox, SQ_SESSION); sqgetGlobalVar('targetMailbox', $lastTargetMailbox, SQ_POST); -- 2.25.1