Skip to content

Fix double charset conversion for non-UTF-8 message bodies#10100

Open
ju-ef wants to merge 1 commit intoroundcube:masterfrom
ju-ef:fix-double-charset-conversion
Open

Fix double charset conversion for non-UTF-8 message bodies#10100
ju-ef wants to merge 1 commit intoroundcube:masterfrom
ju-ef:fix-double-charset-conversion

Conversation

@ju-ef
Copy link

@ju-ef ju-ef commented Feb 24, 2026

Problem

Messages with charset=windows-1251 (quoted-printable encoding) display as garbled text in Roundcube. Other clients (Thunderbird, K-9, mutt) display them correctly.

Root Cause

get_message_part() already converts body charset to UTF-8, but format_part_body() converts it again using $part->charset which still contains the original charset (e.g. windows-1251). This double conversion produces garbled output.

Fix

Check mb_check_encoding() before converting — if body is already valid UTF-8, skip conversion.

Tested

Roundcube 1.6.13 + Stalwart mail server, windows-1251 quoted-printable messages now display correctly.

Related

Similar UTF-8 detection approach used in #10078.

Messages with charset=windows-1251 (quoted-printable encoding) display
as garbled text in Roundcube. Other clients (Thunderbird, K-9, mutt)
display them correctly.

`get_message_part()` already converts body charset to UTF-8, but
`format_part_body()` converts it again using `$part->charset` which
still contains the original charset (e.g. windows-1251). This double
conversion produces garbled output.

Check `mb_check_encoding()` before converting — if body is already
valid UTF-8, skip conversion.

Roundcube 1.6.13 + Stalwart mail server, windows-1251 quoted-printable
messages now display correctly.

Similar UTF-8 detection approach used in roundcube#10078.
@alecpl
Copy link
Member

alecpl commented Feb 25, 2026

I'm not a fun of checking encoding. We should investigate why we do convertion twice, and why more people don't complain. Could you provide a sample message?

@ju-ef
Copy link
Author

ju-ef commented Feb 25, 2026

I can reproduce it via swaks.

  1. generate body:
echo "привет мир" | iconv -t cp1251 | python3 -c "import quopri, sys; sys.stdout.buffer.write(quopri.encodestring(sys.stdin.buffer.read()))"
  1. send via swaks:
swaks -tls -p 587 --auth LOGIN -ap '<password>' -au '<login>' --server '<server>' \
  --to '<to@domain.tld>' --from '<from@domain.tld>' \
  --header "Content-Type: text/plain; charset=windows-1251" \
  --header "Content-Transfer-Encoding: quoted-printable" \
  --body "=EF=F0=E8=E2=E5=F2 =EC=E8=F0"

OK -
mutt, K-9 (stalwart mail server);
Gmail;
raven (wildduck mail server);
SnappyMail (postfix, dovecot);
Roundcube 1.6.0, 1.6.1, 1.6.13 (postfix, dovecot);

Not OK -
Roundcube 1.6.13 (stalwart)

So, it's something wrong with stalwart.
But should be there some fix? as mutt, K-9 work fine

test2.eml
roundcube_inbox

@alecpl
Copy link
Member

alecpl commented Feb 25, 2026

Other clients might use different set of imap commands, some of them just download the mail source and parse it themselves, but Roundcube uses e.g. BODYSTRUCTURE response from the IMAP server. If such a response is invalid...

It works for me also with Cyrus IMAP. So, it's obviously a Stalwart issue. Enable imap_debug to see what's going on. You can also try with $config['imap_disabled_caps'] = ['BINARY'];.

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