-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix message corruption when displaying a base64 encoded message #9290
Conversation
I don't think this is correct. Could you provide a sample message that does not work? I'm not sure that "every line is a valid base64 string" is true. |
Here's the beginning of a Logwatch message, logwatch encodes the header in one "base64 message" and then the next part is another "base64 message", then there''s a third one; all these are part of the same mail. Roundcube will try to decode the message as a whole producing a lot of garbage, meanwhile if you decode the same message line by line it will produce a proper output. Of course one can get any kind of garbage in a email, but base64 encoded emails are usually fixed width, allowing line by line decoding. Example:
|
RFC2045: All line breaks or other characters not found in Table 1 must be ignored by decoding software. Also https://bugzilla.redhat.com/show_bug.cgi?id=1123093 Processing line by line is not correct because lines might have a length that will not allow to decode them. And I think it is more common case than yours. We could try to detect '=' and act accordingly, I suppose. |
You are right, this seems to be the best way to deal with it.
|
Co-authored-by: Michael Voříšek <mvorisek@mvorisek.cz>
$chunk = substr($chunk, 0, $length); | ||
$decoded_chunk = ''; | ||
foreach(explode('=', preg_replace('~[^a-zA-Z0-9+=/]~', '', $chunk)) as $line) { | ||
$decoded_chunk .= base64_decode($line); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the &$prev
should probably be still supported
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It must be supported. Also the code with $length % 4
is also important. You should not decode incomplete sequences.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we are basically back to the code I posted, right?
if ($mode == 1) {
$chunk = $prev . preg_replace('|[^a-zA-Z0-9+=/]|', '', $chunk);
$length = strlen($chunk);
if ($length % 4) {
$length = floor($length / 4) * 4;
$prev = substr($chunk, $length);
$chunk = substr($chunk, 0, $length);
} else {
$prev = '';
}
$decoded_chunk = '';
foreach(explode('=', $chunk) as $line) {
$decoded_chunk .= base64_decode($line);
}
return $decoded_chunk;
}
You have a sample message here. Sometimes the delimiter is |
@SolracLeinad Please resolve the conflicts and add tests to this, that would help! |
Fixed in 613629f. |
It's 2023 and I'm still experiencing this bug: #4879
The problem is roundcube tries to decode the whole chunk as one big base64 string and while some clients might encode the whole message in one big chunk, some others will do it in several chunks. Decoding multiple base64 strings as one will corrupt the message.
To ammend this, we will decode the whole message line by line because every line is a valid base64 string.