Search code examples
phpemaildecodingyahoo-mail

PHP Invalid quoted-printable sequence, malformed q encoding from Yahoo


I came across the following error in PHP generated by an email forwarded from a Yahoo account:

Notice: Unknown: Invalid quoted-printable sequence: =?UTF-8?Q?ck-off with Weekly Sale up to 90% off (errflg=3) in Unknown on line 0

I've spent hours researching this issue and decided to send myself the exact same output string in an email without having Yahoo involved. The original q-encoded text that decodes correctly:

=?UTF-8?Q?GOG_Forward=3A_Fw=3A_=F0=9F=98=89_A_great_Monday_kick-?= =?UTF-8?Q?off_with_Weekly_Sale_up_to_90=25_off?=

The malformed q-encoded text from Yahoo:

=?UTF-8?Q?GOG_Forward =?UTF-8?Q?ck-off_with_Weekly_Sale_up_to_90%_off?=

The correct string when decoded:

GOG Forward: Fw: 😉 A great Monday kick-off with Weekly Sale up to 90% off

Roundcube manages to decode both the normal and the malformed text though I'm not sure how and 25 megabytes is a bit much to dig through and I haven't been able to determine even where they're decoding subject headers.

How do I fix Yahoo's malformed version of q-encoding?

<?php
//These fail:
echo imap_mime_header_decode($mail_message_headers['Subject']);
echo quoted_printable_decode($mail_message_headers['Subject']);
?>

For clarification the imap_fetchstructure page clarifies the value 4 for encoding is Quoted-Printable / ENCQUOTEDPRINTABLE.


New Development

It turns out that for some reason Yahoo sends the subject twice for the same header, one malformed and the other is not. Here is the Subject header from the raw email:

Subject: =?UTF-8?Q?GOG_Forward:_Fw:_=F0=9F=98=89_A_great_Monday_ki?=
 =?UTF-8?Q?ck-off_with_Weekly_Sale_up_to_90%_off?=
MIME-Version: 1.0

Solution

  • I created a solution that uses Roundcube's source code to decode the message.

    I posted the code and demo:

    • You can see it here
    • Click the big play button to preview the extraction
    • Go to code tab to see the extracted Roundcube code that you could use for your project

    Since you mentioned to not use classes in the example I extracted Roundcube's decode_mime_string() function from rube_mime, and a couple of things from rcube_charset such as $aliases, parse_charset(), and convert().


    As far as decoding the malformed text from Yahoo:

    =?UTF-8?Q?GOG_Forward =?UTF-8?Q?ck-off_with_Weekly_Sale_up_to_90%_off?=

    Into this:

    GOG Forward: Fw: 😉 A great Monday kick-off with Weekly Sale up to 90% off

    It's impossible. There's not enough data in there. For example it's missing the "😉 A great Monday ki". Do you have the full source of the email address?