(geronimo-mail) 03/07: GERONIMO-6897 - Folder.create() sends the uninitialized hierarchy separator, creating a mailbox named "name\0"
[email protected] Sat, 18 Jul 2026 18:49:02 +0000
| Newsgroups | gmane.comp.java.geronimo.cvs |
|---|---|
| Message-ID | <[email protected]> |
This is an automated email from the ASF dual-hosted git repository. rzo1 pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/geronimo-mail.git commit f09957901b3d63af6b8cc20ebeddaeff8ee34590 Author: Richard Zowalla <[email protected]> AuthorDate: Sat Jul 18 20:48:28 2026 +0200 GERONIMO-6897 - Folder.create() sends the uninitialized hierarchy separator, creating a mailbox named "name\0" --- .../geronimo/mail/store/imap/IMAPFolder.java | 20 +++++++++++--- .../mail/store/imap/IMAPTckRegressionTest.java | 31 ++++++++++++++++++++++ geronimo-mail_2.1_tck/src/tck/geronimo.jtx | 3 --- 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/geronimo-mail_2.1_impl/geronimo-mail_2.1_provider/src/main/java/org/apache/geronimo/mail/store/imap/IMAPFolder.java b/geronimo-mail_2.1_impl/geronimo-mail_2.1_provider/src/main/java/org/apache/geronimo/mail/store/imap/IMAPFolder.java index f228d24..d94d6e8 100644 --- a/geronimo-mail_2.1_impl/geronimo-mail_2.1_provider/src/main/java/org/apache/geronimo/mail/store/imap/IMAPFolder.java +++ b/geronimo-mail_2.1_impl/geronimo-mail_2.1_provider/src/main/java/org/apache/geronimo/mail/store/imap/IMAPFolder.java @@ -326,9 +326,19 @@ public class IMAPFolder extends Folder implements UIDFolder, IMAPUntaggedRespons List responses = connection.list("", fullname); IMAPListResponse info = findListResponse(responses, fullname); - // if we didn't get any hits, then we just assume a reasonable default. + // if we didn't get any hits (e.g., the folder does not exist yet), + // ask the server for the hierarchy delimiter directly. RFC 3501 + // defines the special form LIST "" "" as returning the hierarchy + // delimiter and the root name without matching any mailboxes. if (info == null) { - separator = '/'; + List delimiterResponses = connection.list("", ""); + if (!delimiterResponses.isEmpty()) { + separator = ((IMAPListResponse)delimiterResponses.get(0)).separator; + } + // no useful answer from the server, assume a reasonable default. + if (separator == '\0') { + separator = '/'; + } } else { separator = info.separator; @@ -384,7 +394,11 @@ public class IMAPFolder extends Folder implements UIDFolder, IMAPUntaggedRespons // if this folder is expected to only hold additional folders, we need to // add a separator on to the end when we create this. if ((newType & HOLDS_MESSAGES) == 0) { - newPath = fullname + separator; + // NB: we must use getSeparator() here, not the raw field. For folders + // obtained from the default folder the separator is still UNDETERMINED + // ('\0'), and appending that raw character would send a corrupted + // (modified-UTF-7 encoded) mailbox name to the server. + newPath = fullname + getSeparator(); } try { // go create this diff --git a/geronimo-mail_2.1_impl/geronimo-mail_2.1_provider/src/test/java/org/apache/geronimo/mail/store/imap/IMAPTckRegressionTest.java b/geronimo-mail_2.1_impl/geronimo-mail_2.1_provider/src/test/java/org/apache/geronimo/mail/store/imap/IMAPTckRegressionTest.java index 667f94f..57c11d8 100644 --- a/geronimo-mail_2.1_impl/geronimo-mail_2.1_provider/src/test/java/org/apache/geronimo/mail/store/imap/IMAPTckRegressionTest.java +++ b/geronimo-mail_2.1_impl/geronimo-mail_2.1_provider/src/test/java/org/apache/geronimo/mail/store/imap/IMAPTckRegressionTest.java @@ -27,7 +27,9 @@ import jakarta.mail.Store; import org.apache.geronimo.mail.testserver.AbstractProtocolTest; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * Regression tests for a set of IMAP provider defects surfaced by the @@ -62,6 +64,35 @@ public class IMAPTckRegressionTest extends AbstractProtocolTest { server.appendToUserMailbox(name, readMessageResource("/messages/simple.msg")); } + /** + * Folder#create_Test/delete_Test/getType_Test: a top-level folder obtained + * via the default folder has an UNDETERMINED separator; create() used to + * append the raw '\0' separator to the mailbox name on the wire + * ("CREATE topdog&AAA-"), so the folder was created under a mangled name + * and create() reported failure. The James hierarchy delimiter is '.', + * not the '/' fallback, so the separator must be obtained from the server. + */ + @Test + public void testCreateDeleteGetTypeRoundTrip() throws Exception { + start(); + + final Store store = connect(); + try { + final Folder folder = store.getDefaultFolder().getFolder("topdog"); + assertFalse(folder.exists(), "folder must not exist before creation"); + + assertTrue(folder.create(Folder.HOLDS_FOLDERS), "create must succeed"); + assertTrue(folder.exists(), "created folder must exist under its own name"); + assertTrue((folder.getType() & Folder.HOLDS_FOLDERS) != 0, + "created folder must be able to hold folders"); + + assertTrue(folder.delete(false), "delete must succeed"); + assertFalse(folder.exists(), "deleted folder must no longer exist"); + } finally { + store.close(); + } + } + /** * MimeMessage#getContentLanguage_Test: a message whose BODYSTRUCTURE * carries no language information used to trigger a NullPointerException; diff --git a/geronimo-mail_2.1_tck/src/tck/geronimo.jtx b/geronimo-mail_2.1_tck/src/tck/geronimo.jtx index 0cbef10..9a534c2 100644 --- a/geronimo-mail_2.1_tck/src/tck/geronimo.jtx +++ b/geronimo-mail_2.1_tck/src/tck/geronimo.jtx @@ -43,10 +43,7 @@ javasoft/sqe/tests/jakarta/mail/Folder/testlist.html#appendMessages_Test javasoft/sqe/tests/jakarta/mail/event/FolderEvent/testlist.html#addMsgChangeList_Test javasoft/sqe/tests/jakarta/mail/exception/testlist.html#folderNotFoundExp_Test javasoft/sqe/tests/jakarta/mail/exception/testlist.html#msgRemoveExp_Test -javasoft/sqe/tests/jakarta/mail/Folder/testlist.html#create_Test -javasoft/sqe/tests/jakarta/mail/Folder/testlist.html#delete_Test javasoft/sqe/tests/jakarta/mail/Folder/testlist.html#getPermanentFlags_Test -javasoft/sqe/tests/jakarta/mail/Folder/testlist.html#getType_Test javasoft/sqe/tests/jakarta/mail/Folder/testlist.html#list_Test javasoft/sqe/tests/jakarta/mail/Folder/testlist.html#listSubscribed_Test javasoft/sqe/tests/jakarta/mail/internet/InternetAddress/testlist.html#unicode_Test