Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 26, 2026

IMAP operations were failing with "Invalid quoted-printable sequence" when thread titles containing malformed MIME-encoded strings (from email subjects) were used as folder names.

Changes

ThreadFolderManager: Decode MIME headers before generating folder names

  • Detect MIME-encoded strings via =? marker
  • Apply mb_decode_mimeheader() only when needed to preserve UTF-8 text
  • Handles both valid and malformed MIME headers gracefully

ImapWrapper: Add defensive error handling in utf8()

  • Check for IMAP errors after imap_utf8() call
  • Fallback to mb_decode_mimeheader() on decode failures
  • Log errors without throwing to prevent crashes

Example

Before this fix, a thread title like:

=?iso-8859-1?Q?axz5ZAFym5luZoxqfgeds8xO/E+PtRicCu3CXJTfFFl7/aub8+5SDA59PR? =?iso-

Would be passed directly to imap_mail_move(), causing the IMAP server to fail decoding it.

After the fix, it's decoded to:

axz5ZAFym5luZoxqfgeds8xO-E+PtRicCu3CXJTfFFl7-aub8+5SDA59PR- =so-

With all MIME markers removed and invalid folder characters sanitized.

Original prompt

An error occurred in the Offpost system:

Source: scheduled-imap-handling
Time: 2026-01-26 17:29:07 CET
Message: Unexpected error: IMAP error during mailMove: Invalid quoted-printable sequence:
=?iso-8859-1?Q?axz5ZAFym5luZoxqfgeds8xO/E+PtRicCu3CXJTfFFl7/aub8+5SDA59PR? =?iso-

Error Details:
file: /php-frontend/class/Imap/ImapWrapper.php
line: 50
stack_trace: #0 /php-frontend/class/Imap/ImapWrapper.php(220): Imap\ImapWrapper->checkError('mailMove', NULL, true)
#1 /php-frontend/class/Imap/ImapConnection.php(187): Imap\ImapWrapper->mailMove(Object(IMAP\Connection), '7828106', 'INBOX.964968330...', 1)
#2 /php-frontend/class/Imap/ImapFolderManager.php(65): Imap\ImapConnection->moveEmail(7828106, 'INBOX.964968330...')
#3 /php-frontend/class/ThreadEmailMover.php(108): Imap\ImapFolderManager->moveEmail(7828106, 'INBOX.964968330...')
#4 /php-frontend/update-imap-functions.php(130): ThreadEmailMover->processMailbox('INBOX', Array)
#5 /php-frontend/system-pages/scheduled-imap-handling.php(59): processInbox(Object(Imap\ImapConnection), Object(Imap\ImapFolderManager),
Object(Imap\ImapEmailProcessor), Array)
#6 /php-frontend/webroot/index.php(38): require('/php-frontend/s...')
#7 {main}
debug_output:

Please check the system logs for more information.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 4 commits January 26, 2026 17:51
Co-authored-by: HNygard <168380+HNygard@users.noreply.github.com>
…headers

Co-authored-by: HNygard <168380+HNygard@users.noreply.github.com>
…rors

Co-authored-by: HNygard <168380+HNygard@users.noreply.github.com>
Co-authored-by: HNygard <168380+HNygard@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix IMAP error during mailMove in Offpost system Fix IMAP mailMove crash on malformed MIME-encoded thread titles Jan 26, 2026
Copilot AI requested a review from HNygard January 26, 2026 17:56
@HNygard HNygard marked this pull request as ready for review January 27, 2026 06:55
Copilot AI review requested due to automatic review settings January 27, 2026 06:55
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a crash in IMAP operations when thread titles contain malformed MIME-encoded strings from email subjects. The issue occurred when these encoded strings were used as IMAP folder names, causing imap_mail_move() to fail with "Invalid quoted-printable sequence" errors.

Changes:

  • Added MIME header decoding in ThreadFolderManager before generating folder names
  • Enhanced error handling in ImapWrapper.utf8() to gracefully handle malformed MIME strings
  • Added comprehensive test coverage for both valid and malformed MIME-encoded strings

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
organizer/src/class/ThreadFolderManager.php Decodes MIME-encoded thread titles before generating IMAP folder names, preventing malformed strings from being passed to IMAP operations
organizer/src/class/Imap/ImapWrapper.php Adds defensive error handling to utf8() method with fallback to mb_decode_mimeheader() when imap_utf8() fails
organizer/src/tests/ThreadFolderManagerTest.php Adds tests for both malformed and valid MIME-encoded thread titles to ensure proper decoding and sanitization
organizer/src/tests/ImapWrapperUtf8Test.php Adds comprehensive test coverage for utf8() method including normal text, valid/malformed MIME strings, and special characters

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 70 to +76
$title = $entity_id . ' - ' . $thread->title;

// Decode any MIME-encoded headers (e.g., =?UTF-8?B?...?= or =?iso-8859-1?Q?...?=)
// Only decode if the string contains MIME encoding markers to avoid corrupting UTF-8 text
if (strpos($title, '=?') !== false) {
$title = mb_decode_mimeheader($title);
}
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The MIME decoding happens on the combined string $entity_id . ' - ' . $thread->title. If the entity_id contains the marker =?, it would trigger unnecessary MIME decoding. While entity_ids are unlikely to contain such markers in practice, consider checking for MIME markers specifically in $thread->title before combining, or document this assumption to prevent future issues.

Suggested change
$title = $entity_id . ' - ' . $thread->title;
// Decode any MIME-encoded headers (e.g., =?UTF-8?B?...?= or =?iso-8859-1?Q?...?=)
// Only decode if the string contains MIME encoding markers to avoid corrupting UTF-8 text
if (strpos($title, '=?') !== false) {
$title = mb_decode_mimeheader($title);
}
// Decode MIME-encoded thread title (if any) before combining with entity_id
$decodedTitle = $thread->title;
// Decode any MIME-encoded headers (e.g., =?UTF-8?B?...?= or =?iso-8859-1?Q?...?=)
// Only decode if the string contains MIME encoding markers to avoid corrupting UTF-8 text
if (strpos($decodedTitle, '=?') !== false) {
$decodedTitle = mb_decode_mimeheader($decodedTitle);
}
$title = $entity_id . ' - ' . $decodedTitle;

Copilot uses AI. Check for mistakes.
Comment on lines +30 to +41
public function testUtf8WithMalformedMimeEncodedString()
{
$wrapper = new ImapWrapper();
// Malformed MIME-encoded string from the error report
$text = '=?iso-8859-1?Q?axz5ZAFym5luZoxqfgeds8xO/E+PtRicCu3CXJTfFFl7/aub8+5SDA59PR? =?iso-';

// This should not throw an exception
$result = $wrapper->utf8($text);

// Should return a string (may be the same as input if imap_utf8 can't decode it)
$this->assertIsString($result);
}
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test verifies that the function doesn't throw an exception and returns a string, but it doesn't validate what the decoded output is for the malformed MIME string. Consider adding an assertion to check that MIME markers are removed from the result, similar to the ThreadFolderManagerTest assertions at lines 284-286, to ensure the fallback decoding logic works as expected.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants