ikvk / imap_tools

Work with email by IMAP
Apache License 2.0
719 stars 83 forks source link

Fix double quotes in folder name #240

Closed histogal closed 3 months ago

histogal commented 3 months ago

I have next LIST response: LIST (\HasNoChildren) "/" "Folder/Subfolder \"i am subfolder\""

at 134 line name will be Folder/Subfolder \\"i am subfolder\\". and encode_folder->quote transform it to: "Folder/Subfolder \\\\\\"i am subfolder\\\\\\""

We need unquote it.

ikvk commented 3 months ago

We need unquote it - for what? It works as expected.

histogal commented 3 months ago

Ok. Look:

You quoting folder name when request operation, but never unquoting it when server response with quoted folder name.

ikvk commented 3 months ago

here is small example: (yandex mail)

folder_name = 'zz|"123"'
for f in mailbox.folder.list(folder_name):
    print(f.name)
    # print(' - ', mailbox.folder.status(f.name, [MailBoxFolderStatusOptions.UNSEEN]))
print(mailbox.folder.status(folder_name))

All works:

zz|"123" {'MESSAGES': 1, 'RECENT': 1, 'UNSEEN': 0, 'UIDNEXT': 9, 'UIDVALIDITY': 1587625216}

Why are you trying to escape double quotes in name for .status()? - _encodefolder->quote transform it to:

histogal commented 3 months ago

Why are you trying to escape double quotes in name for .status()? - encode_folder->quote transform it to:

i don't trying, it's in https://github.com/ikvk/imap_tools/blob/1d523fa930742d08b0946e0a748eb9d68e2add10/imap_tools/folder.py#L100C22-L100C35. And in other functions.

here is small example: (yandex mail)

When you LIST 'zz|"123"', it pass to encode_folder and quotes normal.

Can you show raw LIST answer for parent of 'zz|"123"'? Maybe after _untagged_response (at line 122 folder.py) of from curl? And add some spaces in folder name please, if you can. Imap server will add some additional quotes, if i understand correctly. At least my server adds =(

In my case when i LIST "Folder" * i receive LIST (\HasNoChildren) "/" "Folder/Subfolder \"i am subfolder\"". And then it breaks as I wrote above.

histogal commented 3 months ago

And if we look in RFC 3501:

  1. mailbox = "INBOX" / astring
  2. astring = 1*ASTRING-CHAR / string
  3. string = quoted / literal
  4. quoted = DQUOTE *QUOTED-CHAR DQUOTE
  5. QUOTED-CHAR = <any TEXT-CHAR except quoted-specials> / "\" quoted-specials
  6. quoted-specials = DQUOTE / "\"

If we try to decompose from bottom to top: mailbox = "INBOX" / ( 1*ASTRING-CHAR / ( DQUOTE *( <any TEXT-CHAR except quoted-specials> / "\" ( DQUOTE / "\" ) DQUOTE ) / literal ) )

This means that if name contains double quote or backslash it will be escaped \" or \\. And than we should unescape that.

ikvk commented 3 months ago

Thanks for your investigation, I will find time to check code and fix it.

ikvk commented 3 months ago

check it https://github.com/ikvk/imap_tools/releases/tag/v1.7.2

Thanks!