diff --git a/docs/release-testing-0.7.md b/docs/release-testing-0.7.md index bcd8709..4f82924 100644 --- a/docs/release-testing-0.7.md +++ b/docs/release-testing-0.7.md @@ -174,7 +174,7 @@ review does not mark an open live test as passed. | IMAP-05 | LIST, LSUB, extended LIST, LIST-STATUS, hierarchy quoting | [PASS](test-evidence/0.7-r1.md#imap-0506) | | | | IMAP-06 | CREATE, DELETE, RENAME, SUBSCRIBE, UNSUBSCRIBE | [PASS](test-evidence/0.7-r1.md#imap-0506) | | | | IMAP-07 | SELECT, EXAMINE, STATUS/SIZE, CHECK, CLOSE, UNSELECT | [PASS](test-evidence/0.7-r1.md#imap-07) | | | -| IMAP-08 | APPEND, LITERAL+, APPENDLIMIT, flags/date, oversized literals | | | | +| IMAP-08 | APPEND, LITERAL+, APPENDLIMIT, flags/date, oversized literals | [PASS](test-evidence/0.7-r1.md#imap-08) | | | | IMAP-09 | FETCH/UID FETCH body, headers, partials, flags, envelope, binary | | | | | IMAP-10 | STORE/UID STORE add/remove/replace flags and silent variants | | | | | IMAP-11 | COPY/UID COPY/MOVE/UID MOVE and UIDPLUS response codes | | | | diff --git a/docs/test-evidence/0.7-r1.md b/docs/test-evidence/0.7-r1.md index 58f3f85..ac8b2ff 100644 --- a/docs/test-evidence/0.7-r1.md +++ b/docs/test-evidence/0.7-r1.md @@ -3367,7 +3367,7 @@ document, and left `bongo.service` active. Result: **PASS** -The installed `865c632d` GCC 15.3.0 debug build was exercised on 2026-07-29 +The installed `834c9322` GCC 15.3.0 debug build was exercised on 2026-07-29 with the reusable `smtp-tlsrpt-delivery-check.py --live` fixture. It delivered one RFC 8460 report as a DKIM-signed, gzip-compressed MIME attachment and one gzip-compressed report through HTTPS with validated TLS. Reports with a @@ -3447,15 +3447,21 @@ GSASL PLAIN and LOGIN mechanisms. The TLS capability response contained an RFC 2971 client ID with name and version, the RFC 2342 personal namespace, and LOGOUT with an untagged BYE followed by tagged completion. -This state model was compared with current Cyrus IMAP `imap/imapd.c`. Cyrus -likewise limits STARTTLS and SASL-IR to pre-authentication state, advertises -`LOGINDISABLED` from connection state, starts TLS immediately for IMAPS, and -explicitly discards input pipelined after STARTTLS. Bongo's focused +This state model was compared with Cyrus IMAP 3.12.3 `imap/imapd.c` and +Dovecot 2.4.4 `src/imap/imap-commands.c`, +`src/imap-login/client-authenticate.c`, +`src/login-common/client-common-auth.c`, and `src/imap/cmd-id.c`. The source +comparison added checks for AUTHENTICATE cancellation, malformed base64, +unknown mechanisms, trailing arguments, continued session usability, ID +field limits, NIL keys, literals, and commands which take no arguments. +Cyrus and Dovecot likewise limit STARTTLS and SASL-IR to pre-authentication +state, derive `LOGINDISABLED` from connection state, and discard input +pipelined after STARTTLS. Bongo's focused `imap-capabilities`, `imap-protocol`, and `sasl-password-mechanisms` native tests all passed before the live run. ```text -IMAP-01/02/03/04 PASS host=127.0.0.1 starttls=143/TLSv1.3 imaps=993/TLSv1.3 protocols=IMAP4rev2,IMAP4rev1,IMAP4 pre-tls=LOGINDISABLED login=LOGIN,PLAIN,LOGIN-SASL commands=CAPABILITY,NOOP,ID,NAMESPACE,LOGOUT repeated-starttls=rejected pipeline=discarded +IMAP-01/02/03/04 PASS host=127.0.0.1 starttls=143/TLSv1.3 imaps=993/TLSv1.3 protocols=IMAP4rev2,IMAP4rev1,IMAP4 pre-tls=LOGINDISABLED login=LOGIN,PLAIN,LOGIN-SASL commands=CAPABILITY,NOOP,ID,NAMESPACE,LOGOUT id=literal+,limits,nil-key-rejected auth=cancel/unknown/base64/trailing/session-alive noarg-syntax=capability/noop/namespace/logout repeated-starttls=rejected pipeline=discarded ``` The test only authenticates and logs out. It does not create, alter, or @@ -3465,7 +3471,7 @@ delete any mailbox or message and leaves the service configuration unchanged. Result: **PASS** -The installed `9bb5eb8e` GCC 15.3.0 debug build was exercised on 2026-07-29 +The installed `834c9322` GCC 15.3.0 debug build was exercised on 2026-07-29 with the reusable `imap-mailbox-check.py`. The test used disposable mailbox names containing spaces and multiple hierarchy levels. It verified the reported hierarchy delimiter, LIST with both `%` and `*`, exact and recursive @@ -3474,26 +3480,37 @@ LIST-STATUS responses. CREATE left new mailboxes unsubscribed until an explicit SUBSCRIBE. RENAME moved the complete hierarchy without changing any child or grandchild suffix. -UNSUBSCRIBE removed only the subscription. DELETE removed an empty leaf, and -deleting a parent with inferiors retained its children while converting the -parent into a `\NoSelect` hierarchy placeholder. The test then removed all -disposable objects depth-first and verified that none remained. +UNSUBSCRIBE removed only the subscription. DELETE retained subscriptions +independently of mailbox existence: obsolete LSUB continued to return the +deleted name, extended LIST returned `\Subscribed \NonExistent`, basic LIST +returned `\NoSelect`, and CREATE restored the selectable mailbox without +dropping its subscription. Deleting a parent with inferiors retained its +children. A final UNSUBSCRIBE removed an unused non-existent placeholder. +The test then removed all disposable objects depth-first and verified that +none remained. -The live pass exposed and fixed three issues before succeeding: CREATE had +The live pass exposed and fixed several issues before succeeding: CREATE had implicitly subscribed folders, recursive Store rename truncated hierarchy -suffixes, and Store commands did not quote paths containing spaces when -converting a deleted parent to hierarchy-only state. Focused native coverage -now exercises SPECIAL-USE creation, LIST-EXTENDED parsing, and the exact SQL -rename boundary for children, grandchildren, and similarly prefixed -mailboxes. +suffixes, LSUB overwrote a syntax error with a path-length error, wildcard and +reference handling were incomplete, INBOX was not canonicalized +case-insensitively, subscriptions disappeared with a deleted mailbox, and +several Store commands did not quote paths containing spaces. The missing +quotes also caused the old CREATE error path to return without a tagged IMAP +response. Focused native coverage now exercises SPECIAL-USE creation, +LIST-EXTENDED parsing, and the exact SQL rename boundary for children, +grandchildren, and similarly prefixed mailboxes. -The behavior was also compared directly with current Cyrus IMAP source: -subscription is independent of mailbox creation, hierarchy rename preserves -descendants, and deleting a mailbox with inferiors leaves the hierarchy -available for those descendants. +The behavior was compared directly with Cyrus IMAP 3.12.3 +`imap/imapd.c` (`cmd_changesub`, LIST processing, rename and delete paths) and +Dovecot 2.4.4 `src/imap/cmd-list.c`, `src/imap/cmd-subscribe.c`, and +`src/lib-storage/mailbox-list.c`. Both implementations keep subscriptions +separate from mailbox existence. Dovecot's `used_listext` distinction was +also used to preserve the RFC difference between basic `\NoSelect` and +extended `\NonExistent` responses. RFC 9051 sections 6.3.7 through 6.3.9 were +checked alongside both implementations. ```text -IMAP-05/06 PASS host=127.0.0.1:993 delimiter=/ hierarchy=quoted list=percent/star lsub=subscribed-only extended=subscribed/children/list-status lifecycle=create/rename/sub/unsub/delete delete-with-inferiors=noselect/preserved cleanup=yes +IMAP-05/06 PASS host=127.0.0.1:993 delimiter=/ hierarchy=quoted list=percent/star/literal-pattern-list/reference/inbox-case lsub=subscribed-only lsub=mid-wildcard/no-match/delimiter extended=subscribed/children/list-status lifecycle=create/rename/sub/unsub/delete syntax=trailing-arguments-rejected delete-subscription=retained/nonexistent/recreated delete-with-inferiors=noselect/preserved cleanup=yes ``` The test creates only uniquely named disposable mailboxes for `test1`, removes @@ -3503,7 +3520,7 @@ them before exit, and does not alter service configuration or existing mail. Result: **PASS** -The installed `0c0d281b` GCC 15.3.0 debug build was exercised on 2026-07-29 +The installed `834c9322` GCC 15.3.0 debug build was exercised on 2026-07-29 with the reusable `imap-selected-state-check.py`. The test created two disposable mailboxes and appended one disposable message using a synchronizing IMAP literal. Rev1 SELECT returned EXISTS, RECENT, UIDVALIDITY, UIDNEXT, FLAGS, @@ -3519,10 +3536,12 @@ After `ENABLE IMAP4rev2`, STATUS accepted DELETED and DELETED-STORAGE but rejected RECENT; SELECT omitted RECENT, emitted the required LIST response, and selecting a second mailbox emitted the CLOSED response code. -The source audit used current Cyrus IMAP `imap/imapd.c` as the implementation -comparison. Cyrus likewise separates EXAMINE read-only state, expunges on -CLOSE but not UNSELECT, emits CLOSED when rev2 selection replaces an open -mailbox, and refreshes selected-mailbox state before STATUS. +The source audit used Cyrus IMAP 3.12.3 `imap/imapd.c` and Dovecot 2.4.4 +`src/imap/cmd-select.c`, `cmd-examine.c`, `cmd-status.c`, `cmd-close.c`, +`cmd-unselect.c`, and the command registration table as implementation +comparisons. Both separate EXAMINE read-only state, expunge on CLOSE but not +UNSELECT, reject arguments on CHECK/CLOSE/UNSELECT, and implement the rev2 +CLOSED transition when a selected mailbox is replaced. The first live attempt found a real APPEND deadlock: the IMAP agent buffered the message sent to Store and waited for Store's completion without flushing @@ -3533,9 +3552,57 @@ returns only its payload. The corrected payload parser is covered by the native `imap-uidplus` test and also fixes the later COPY/MOVE UIDPLUS paths. ```text -IMAP-07 PASS host=127.0.0.1:993 select=read-write examine=read-only status=rev1/rev2/size check=selected-only close=deselect/expunge-semantics unselect=no-expunge rev2=closed/list/no-recent cleanup=yes +IMAP-07 PASS host=127.0.0.1:993 select=read-write examine=read-only status=rev1/rev2/size check=selected-only noarg-syntax=check/close/unselect close=deselect/expunge-semantics unselect=no-expunge rev2=closed/list/no-recent cleanup=yes ``` The successful run removed its disposable message and mailboxes. The three mailboxes left by deliberately interrupted diagnostic runs were separately listed, matched by their unique test names, and removed afterward. + +## IMAP-08 + +Result: **PASS** + +The installed `834c9322` GCC 15.3.0 debug build was exercised on 2026-07-29 +with the reusable `imap-append-check.py`. Synchronizing literals and +non-synchronizing LITERAL+ both committed messages and returned UIDPLUS +APPENDUID data. Supplied system flags and INTERNALDATE survived the append. +APPEND to a missing mailbox returned TRYCREATE. The advertised global +APPENDLIMIT and per-mailbox STATUS APPENDLIMIT agreed, an oversized +non-synchronizing literal returned TOOBIG without accepting its body, and the +next command proved that the parser stream remained synchronized. + +The implementation was compared with Cyrus IMAP 3.12.3 `imap/imapd.c` append +handling and Dovecot 2.4.4 `src/imap/cmd-append.c` plus its command/literal +reader. The comparison covered literal continuation timing, LITERAL+, +mailbox lookup before data acceptance, bounded literal sizes, flag/date +parsing, failure stream recovery, and UIDPLUS completion. RFC 9051 and the +advertised APPENDLIMIT/LITERAL+ extension contracts were checked at the same +time. + +The native `imap-append-message`, `imap-literal`, and `imap-uidplus` tests +passed as part of the complete 101-test native run before the live matrix. + +```text +IMAP-08 PASS host=127.0.0.1:993 append=sync/literal+ appendlimit=capability/status/toobig metadata=flags/date missing=trycreate stream=resynchronized cleanup=yes +``` + +The test removed all disposable messages and mailboxes and did not change +service configuration. + +## IMAP retrospective source audit + +Result: **PASS for IMAP-01 through IMAP-08** + +The already completed IMAP blocks were re-audited against actual current +server source, not only documentation: Cyrus IMAP 3.12.3 and Dovecot 2.4.4. +The comparison found and fixed authentication cancellation/error handling, +ID and no-argument syntax validation, LIST/LSUB parsing and wildcard +semantics, case-insensitive INBOX handling, independent subscription +lifetime, basic-versus-extended LIST attributes, missing Store path quoting, +and several error paths which could otherwise omit a tagged response. + +After the fixes, all 101 native tests passed and the four reusable live +scripts for IMAP-01 through IMAP-08 passed consecutively against the +installed debug build. The same Cyrus/Dovecot source-comparison requirement +applies to every remaining IMAP and POP3 row as it is reached in the matrix.