jstedfast / MailKit

A cross-platform .NET library for IMAP, POP3, and SMTP.
http://www.mimekit.net
MIT License
6.04k stars 809 forks source link

[Yandex] GetBodyPart() throws `Syntax error in BODY. Unexpected token: ')'` for MimeParts with empty content #1708

Closed sq5 closed 4 months ago

sq5 commented 4 months ago

Discussed in https://github.com/jstedfast/MailKit/discussions/1707

Originally posted by **sq5** February 12, 2024 Mailkit Version 4.3.0, mail server - Yandex Error: Exception has occurred: CLR/MailKit.Net.Imap.ImapProtocolException Exception thrown: 'MailKit.Net.Imap.ImapProtocolException' in System.Private.CoreLib.dll: 'Syntax error in BODY. Unexpected token: ')'' at MailKit.Net.Imap.ImapFolder.d__213.MoveNext() at MailKit.Net.Imap.ImapEngine.d__189.MoveNext() at MailKit.Net.Imap.ImapCommand.d__84.MoveNext() at MailKit.Net.Imap.ImapEngine.d__190.MoveNext() at MailKit.Net.Imap.ImapEngine.d__191.MoveNext() at MailKit.Net.Imap.ImapFolder.d__237.MoveNext() at MailKit.Net.Imap.ImapFolder.GetBodyPart(UniqueId uid, String partSpecifier, CancellationToken cancellationToken, ITransferProgress progress) at MailKit.Net.Imap.ImapFolder.GetBodyPart(UniqueId uid, BodyPart part, CancellationToken cancellationToken, ITransferProgress progress)
jstedfast commented 4 months ago

These types if exceptions are typically due to a syntax error in the server response.

What I need from you is a protocol log. Specifically, the last response from the server when you get this exception.

You can get a protocol log by passing in a new ProtocolLogger ("imap.log") to the ImapClient constructor like this:

var client = new ImapClient (new ProtocolLogger ("imap.log"));
sq5 commented 4 months ago

Please, find it in the attachment imap.log

jstedfast commented 4 months ago

Here's the problem:

S: * 1 FETCH (UID 3016 BODY[2.MIME] {389}
S: Content-Disposition: attachment;
S:  filename="=?UTF-8?B?0KHRh9C10YIg0LTQtCDQotC+0L8t0JrQvtGE0LUg0YPQuy4g0KPRgNCw0LvRjNGB0LrQsNGPLCDQtC4x?=
S:  =?UTF-8?B?INC90L7Rj9Cx0YDRjC5wZGY=?="
S: Content-Transfer-Encoding: base64
S: Content-Type: application/pdf;
S:  name="=?UTF-8?B?0KHRh9C10YIg0LTQtCDQotC+0L8t0JrQvtGE0LUg0YPQuy4g0KPRgNCw0LvRjNGB0LrQsNGPLCDQtC4x?=
S:  =?UTF-8?B?INC90L7Rj9Cx0YDRjC5wZGY=?="
S: 
S:  BODY[2] )

See the BODY[2]? IMAP responds with key/value pairs. In this case, it gives us a key (BODY[2]), but no corresponding value.

A correct response would be any of the following:

S: * 1 FETCH (UID 3016 BODY[2.MIME] {389}
S: Content-Disposition: attachment;
S:  filename="=?UTF-8?B?0KHRh9C10YIg0LTQtCDQotC+0L8t0JrQvtGE0LUg0YPQuy4g0KPRgNCw0LvRjNGB0LrQsNGPLCDQtC4x?=
S:  =?UTF-8?B?INC90L7Rj9Cx0YDRjC5wZGY=?="
S: Content-Transfer-Encoding: base64
S: Content-Type: application/pdf;
S:  name="=?UTF-8?B?0KHRh9C10YIg0LTQtCDQotC+0L8t0JrQvtGE0LUg0YPQuy4g0KPRgNCw0LvRjNGB0LrQsNGPLCDQtC4x?=
S:  =?UTF-8?B?INC90L7Rj9Cx0YDRjC5wZGY=?="
S: 
S:  BODY[2] "")

or

S: * 1 FETCH (UID 3016 BODY[2.MIME] {389}
S: Content-Disposition: attachment;
S:  filename="=?UTF-8?B?0KHRh9C10YIg0LTQtCDQotC+0L8t0JrQvtGE0LUg0YPQuy4g0KPRgNCw0LvRjNGB0LrQsNGPLCDQtC4x?=
S:  =?UTF-8?B?INC90L7Rj9Cx0YDRjC5wZGY=?="
S: Content-Transfer-Encoding: base64
S: Content-Type: application/pdf;
S:  name="=?UTF-8?B?0KHRh9C10YIg0LTQtCDQotC+0L8t0JrQvtGE0LUg0YPQuy4g0KPRgNCw0LvRjNGB0LrQsNGPLCDQtC4x?=
S:  =?UTF-8?B?INC90L7Rj9Cx0YDRjC5wZGY=?="
S: 
S:  BODY[2] NIL)

or

S: * 1 FETCH (UID 3016 BODY[2.MIME] {389}
S: Content-Disposition: attachment;
S:  filename="=?UTF-8?B?0KHRh9C10YIg0LTQtCDQotC+0L8t0JrQvtGE0LUg0YPQuy4g0KPRgNCw0LvRjNGB0LrQsNGPLCDQtC4x?=
S:  =?UTF-8?B?INC90L7Rj9Cx0YDRjC5wZGY=?="
S: Content-Transfer-Encoding: base64
S: Content-Type: application/pdf;
S:  name="=?UTF-8?B?0KHRh9C10YIg0LTQtCDQotC+0L8t0JrQvtGE0LUg0YPQuy4g0KPRgNCw0LvRjNGB0LrQsNGPLCDQtC4x?=
S:  =?UTF-8?B?INC90L7Rj9Cx0YDRjC5wZGY=?="
S: 
S:  BODY[2] {0}
S:  )

I'll see what I can do about adding a work-around.