mirror of
https://github.com/mjl-/mox.git
synced 2025-07-10 06:34:40 +03:00
imapserver: allow creating mailboxes with characters &#*%, and encode mailbox names in imap with imaputf7 when needed
the imapserver started with imap4rev2-only and utf8=only. to prevent potential issues with imaputf7, which makes "&" special, we refused any mailbox with an "&" in the name. we already tried decoding utf7, falling back to using a mailbox name verbatim. that behaviour wasn't great. we now treat the enabled extensions IMAP4rev2 and/or UTF8=ACCEPT as indication whether mailbox names are in imaputf7. if they are, the encoding must be correct. we now also send mailbox names in imaputf7 when imap4rev2/utf8=accept isn't enabled. and we now allow "*" and "%" (wildcard characters for matching) in mailbox names. not ideal for IMAP LIST with patterns, but not enough reason to refuse them in mailbox names. people that migrate may run into this, possibly as blocker. we also allow "#" in mailbox names, but not as first character, to prevent potential clashes with IMAP namespaces in the future. based on report from Damian Poddebniak using https://github.com/duesee/imap-flow and issue #110, thanks for reporting!
This commit is contained in:
@ -2,6 +2,7 @@ package imapserver
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@ -16,6 +17,12 @@ func TestUTF7(t *testing.T) {
|
||||
if (expErr == nil) != (err == nil) || err != nil && !errors.Is(err, expErr) {
|
||||
t.Fatalf("got err %v, expected %v", err, expErr)
|
||||
}
|
||||
if expErr == nil {
|
||||
expInput := utf7encode(output)
|
||||
if expInput != input {
|
||||
t.Fatalf("encoding, got %s, expected %s", expInput, input)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
check("plain", "plain", nil)
|
||||
@ -24,10 +31,19 @@ func TestUTF7(t *testing.T) {
|
||||
check("&Jjo-test&Jjo-", "☺test☺", nil)
|
||||
check("&Jjo-test", "☺test", nil)
|
||||
check("&-", "&", nil)
|
||||
check("&-", "&", nil)
|
||||
check("&Jjo", "", errUTF7UnfinishedShift) // missing closing -
|
||||
check("&Jjo-&-", "", errUTF7SuperfluousShift) // shift just after unshift not allowed, should have been a single shift.
|
||||
check("&AGE-", "", errUTF7UnneededShift) // Just 'a', does not need utf7.
|
||||
check("&☺-", "", errUTF7Base64)
|
||||
check("&YQ-", "", errUTF7OddSized) // Just a single byte 'a'
|
||||
check("&2AHcNw-", "𐐷", nil)
|
||||
check(fmt.Sprintf("&%s-", utf7encoding.EncodeToString([]byte{0xdc, 0x00, 0xd8, 0x00})), "", errUTF7BadSurrogate) // Low & high surrogate swapped.
|
||||
check(fmt.Sprintf("&%s-", utf7encoding.EncodeToString([]byte{0, 1, 0xdc, 0x00})), "", errUTF7BadSurrogate) // ASCII + high surrogate.
|
||||
check(fmt.Sprintf("&%s-", utf7encoding.EncodeToString([]byte{0, 1, 0xd8, 0x00})), "", errUTF7BadSurrogate) // ASCII + low surrogate.
|
||||
check(fmt.Sprintf("&%s-", utf7encoding.EncodeToString([]byte{0xd8, 0x00, 0, 1})), "", errUTF7BadSurrogate) // low surrogate + ASCII.
|
||||
check(fmt.Sprintf("&%s-", utf7encoding.EncodeToString([]byte{0xdc, 0x00, 0, 1})), "", errUTF7BadSurrogate) // high surrogate + ASCII.
|
||||
|
||||
// ../rfc/9051:7967
|
||||
check("~peter/mail/&U,BTFw-/&ZeVnLIqe-", "~peter/mail/台北/日本語", nil)
|
||||
check("&U,BTFw-&ZeVnLIqe-", "", errUTF7SuperfluousShift)
|
||||
}
|
||||
|
Reference in New Issue
Block a user