chadxz / imap-simple

Wrapper over node-imap, providing a simpler api for common use cases
MIT License
243 stars 80 forks source link

Problem with text encoding #78

Closed QJonny closed 3 years ago

QJonny commented 4 years ago

Hello, I'm having a little trouble reading some emails. The problem is that the text I receive contains strange characters every time an accent exists. Here is what I get in the debugger: body The strange character should actually be a "à". Digging a little bit, I've found that the problem comes from this code: code Here the chunk is actually encoded in ISO-8859-1, but is parsed as utf-8. Is there any way to specify a custom charset?

Thanks

GeraldWodni commented 3 years ago

I was just hunting down the same issue for hours. I fixed it by creating a getMessage which uses buffers instead of strings.

// getMessage without UTF-8
function getMessage(message) {
    return new Promise(function (resolve) {
        var attributes;
        var messageParts = [];
        var isHeader = /^HEADER/g;

        function messageOnBody(stream, info) {
            var body = Buffer.alloc(0);

            function streamOnData(chunk) {
                body = Buffer.concat( [body, chunk] );
            }

            stream.on('data', streamOnData);

            stream.once('end', function streamOnEnd() {
                stream.removeListener('data', streamOnData);

                var part = {
                    which: info.which,
                    size: info.size,
                    body: body,
                };

                if (isHeader.test(part.which)) {
                    part.body = Imap.parseHeader(part.body);
                }

                messageParts.push(part);
            });
        }

        function messageOnAttributes(attrs) {
            attributes = attrs;
        }

        function messageOnEnd() {
            message.removeListener('body', messageOnBody);
            message.removeListener('attributes', messageOnAttributes);
            resolve({
                attributes: attributes,
                parts: messageParts
            });
        }

        message.on('body', messageOnBody);
        message.once('attributes', messageOnAttributes);
        message.once('end', messageOnEnd);
    });
};

Afterwards I overwrote ImapSimple.prototype.getPartData to use the fixed function.

So all that needs to be changed are lines 23 (var body = Buffer.alloc(0);) and 26 (body = Buffer.concat( [body, chunk] );) of helpers/getMessage.js.