Yandex BODYSTRUCTURE CHARSET “X-UNKNOWN”

Yandex does not recognize UTF-8 charset correctly. For a message with text part using utf-8 charset:

Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit

Yandex returns “X-UNKNOWN” as CHARSET instead of correct utf-8 in BODYSTRUCTURE response:

C: 11b7e19c9cd84f0f UID FETCH 1 (UID BODYSTRUCTURE)
S: * 1 FETCH (UID 1 BODYSTRUCTURE (“TEXT” “PLAIN” (CHARSET “X-UNKNOWN”) NIL NIL NIL 11894 0 NIL NIL NIL NIL))

SENTBEFORE doesn’t work correctly on Yahoo IMAP server

Expression.SentBefore doesn’t work correctly on Yahoo IMAP server.

IMAP protocol equivalent of this expression is SENTBEFORE. It examines email’s Date: header.

It appears that although SENTSINCE doesn’t work, SENTSINCE (Expression.SentSince), BEFORE (Expression.Before) and SINCE (Expression.Since) do work correctly. BEFORE and SINCE use email’s INTERNALDATE recorded by the IMAP server instead of Date: header.

C: 0895789b79c64868 UID FETCH 14622 (UID RFC822.SIZE INTERNALDATE ENVELOPE)
S: * 1 FETCH (UID 14622
INTERNALDATE "10-Jun-2014 13:02:08 +0000"
ENVELOPE ("Wed, 10 Jun 2014 15:02:08 +0000" "test2" NIL NIL NIL NIL NIL NIL NIL NIL))
S: 0895789b79c64868 OK UID FETCH completed
C: 2b535791f07e4515 UID SEARCH BEFORE 12-Jun-2014
S: * SEARCH 14622
S: 2b535791f07e4515 OK UID SEARCH completed
C: b726a850e61c4082 UID SEARCH SENTBEFORE 12-Jun-2014
S: * SEARCH
S: b726a850e61c4082 OK UID SEARCH completed
C: 3e479e518dc04915 UID SEARCH BEFORE 13-Jun-2014
S: * SEARCH 14622
S: 3e479e518dc04915 OK UID SEARCH completed
C: 31b7f9ffbe4f4934 UID SEARCH SENTBEFORE 13-Jun-2014
S: * SEARCH
S: 31b7f9ffbe4f4934 OK UID SEARCH completed
C: 2fd2d29b90a24f16 LOGOUT
S: * BYE IMAP4rev1 Server logging out
S: 2fd2d29b90a24f16 OK LOGOUT completed

The fact is that Yahoo IMAP implantation is buggy. Once, the server assigned “17-Jan-1970 05:37:46 +0000” as an INTERNALDATE to one of my emails, just to change that on the next login.

IdeaImapServer IMAP search parentheses bug

IdeaImapServer doesn’t recognize parenthesis in IMAP search command.

RFC 3501 is clear:

A search key can also be a parenthesized list of one or more search keys (e.g., for use with the OR and NOT keys).

Please note that RFC document is not talking, if a server SHOULD or MUST support parentheses. It tells that any search key can always be a parenthesized list.

What is worth mentioning, although IMAP search uses polish notation (which doesn’t need parenthesis by itself) IMAP search command syntax actually requires parentheses.

UID SEARCH (OR SUBJECT subject BODY body) – fails, while:
UID SEARCH OR SUBJECT subject BODY body – succeeds.

This is the log from the server minus the authentication (note that 2nd search returns one email):


S: * OK serwer1476502.home.pl IdeaImapServer v0.80 ready
C: 21a04 CAPABILITY
S: * CAPABILITY IMAP4rev1 LITERAL+ CHILDREN I18NLEVEL=1 IDLE SORT UIDPLUS UNSELECT XLIST AUTH=PLAIN AUTH=LOGIN
C: 98104 UID SEARCH (OR SUBJECT subject BODY body)
S: 98104 BAD Unknown argument: (OR SUBJECT subject BODY body
C: 16e37 UID SEARCH OR SUBJECT subject BODY body
S: * SEARCH 1
S: 16e37 OK Completed

IMAP search requires parentheses

IMAP protocol uses Polish notation (also known as prefix notation) for client queries. In general it means, that operator (in case of IMAP search it’s always a logical operator) is placed left of its operands.

Polish notation

Expression that would be written in conventional infix notation as:
(5 − 6) * 7
can be written in prefix/Polish notation as:
* (− 5 6) 7
As all mathematical operands are binary (or have defined number of operands) we don’t need parentheses to correctly evaluate this expression:
* − 5 6 7

Polish notation doesn’t require parentheses.

IMAP search needs parentheses

Although IMAP search syntax uses Polish notation it actually requires parentheses to be evaluated unambiguously.

This is because there is no explicitly defined AND operator, that takes exactly 2 operands.

RFC 3501:

When multiple keys are specified, the result is the intersection (AND function) of all the messages that match those keys.

So although it is true that Polish and reverse Polish notations don’t require parentheses, it is not true that IMAP search doesn’t require them.

‘OR/AND’ example

Expression 1a:

Regular notation:
(SUBJECT subject OR BODY body) AND FROM from

Polish notation:
AND OR SUBJECT subject BODY body FROM from

IMAP’s Polish notation (note there is no AND operator):
OR SUBJECT subject BODY body FROM from

Expression 1b:

Regular notation:
SUBJECT subject OR (BODY body AND FROM from)

Polish notation:
OR SUBJECT subject AND BODY body FROM from

IMAP’s Polish notation (note there is no AND operator):
OR SUBJECT subject BODY body FROM from

1a != 1b

Expression 1a is not equal to Expression 1b:
((a or b) and c) != (a or (b and c))

For:
a = true
b = true
c = false

We have:
((true or true) and false) != (true or (true and false))
false != true

Parentheses are needed

But when there is no AND operator, IMAP’s Polish notations look exactly the same, thus we need parentheses!

Expression 1a (IMAP’s Polish notation with parentheses):
(OR SUBJECT subject BODY body) FROM from

Expression 1b (IMAP’s Polish notation with parentheses):
OR SUBJECT subject (BODY body FROM from)

OR SUBJECT subject BODY body FROM from
is treated like
(OR SUBJECT subject BODY body) FROM from

‘NOT’ example

Expression 2a:

Regular notation:
NOT (SUBJECT subject AND BODY body)

Polish notation:
NOT AND SUBJECT subject BODY body

IMAP’s Polish notation (note there is no AND operator):
NOT SUBJECT subject BODY body

Expression 2b:

Regular notation:
(NOT SUBJECT subject) AND BODY body

Polish notation:
AND NOT SUBJECT subject BODY body

IMAP’s Polish notation (note there is no AND operator):
NOT SUBJECT subject BODY body

2a != 2b

Expression 2a is obviously not equal to Expression 2b.

Parentheses are needed

Again IMAP’s Polish notations look the same. We need parentheses!

Expression 2a (IMAP’s Polish notation with parentheses):
NOT (SUBJECT subject BODY body)

Expression 2b (IMAP’s Polish notation with parentheses):
(NOT SUBJECT subject) BODY body

NOT SUBJECT subject BODY body
is treated like
(NOT SUBJECT subject) BODY body

Gmail doesn’t send “OK [UNSEEN n]” when required

In IMAP protocol OK [UNSEEN <n>] is a required untagged response to SELECT command. Core IMAP specification (RFC 3501) along with the errata states:

Responses: REQUIRED untagged responses: FLAGS, EXISTS, RECENT
REQUIRED OK untagged responses: PERMANENTFLAGS,
UIDNEXT, UIDVALIDITY, UNSEEN (if any unseen exist)

and later:

If there are any unseen messages in the mailbox, an UNSEEN response MUST be sent, if not it MUST be omitted.

However Gmail IMAP server doesn’t send the OK [UNSEEN <n>] response, even when there are unseen emails in the mailbox. The following listing shows that (note the subsequent SEARCH command that returns a single email):

C: c7a56 SELECT "INBOX"
S: * FLAGS (\Answered \Flagged \Draft \Deleted \Seen $Phishing $MDNSent NonJunk $NotPhishing Junk)
S: * OK [PERMANENTFLAGS (\Answered \Flagged \Draft \Deleted \Seen $Phishing $MDNSent NonJunk $NotPhishing Junk \*)] Flags permitted.
S: * OK [UIDVALIDITY 3] UIDs valid.
S: * 7619 EXISTS
S: * 0 RECENT
S: * OK [UIDNEXT 30566] Predicted next UID.
S: * OK [HIGHESTMODSEQ 2384884]
S: c7a56 OK [READ-WRITE] INBOX selected. (Success)
C: a7c39 UID SEARCH UNSEEN
S: * SEARCH 30565
S: a7c39 OK SEARCH completed (Success)