Skip to content

Generate RFC 5322/2047 compliant folded headers - #1

Open
grammmike wants to merge 15 commits into
masterfrom
rfc5322-folding
Open

grammmike wants to merge 15 commits into
masterfrom
rfc5322-folding

Conversation

@grammmike

Copy link
Copy Markdown
Member

With a finite line length, vmime produced headers that other parsers read back wrong. With an infinite one, encoded-words had no size limit.

  • encoded-words stay within 75 chars, also without a line limit
  • no doubled spaces around encoded-words, which follows up on d296c2d
  • '"' and '' in display names are escaped, and names stay quoted when folded
  • folds are never placed after '', and only at the last space of a run
  • whole addresses move to the next line, with no trailing whitespace and one space before a folded
  • 7-bit local parts are never encoded or folded
  • message-id lists fold in place of the separator
  • the list parser ignores '(', '<' and '"' inside quotes and comments

ABI and soname are unchanged. One test per fix; the suite passes except the pre-existing charsetTest::testConvertStreamExtract. Round trips of random display names through vmime, Python and gromox now show no mismatches. Before, a 60-address list parsed back as 73 addresses.

…ctly (kisli#365)

The length was checked before adding a character and base64 output was
estimated as len*4/3, so chunks could be several chars too long.
RFC 2047 limits an encoded-word to 75 chars. Only the 76 char line
limit was applied, so a word starting at column 0 could be 76
characters long.
… limit (kisli#365)

The limit of RFC 2047 §2 does not depend on the line length. Without
one, the words are separated by a space instead of a fold.
…ut (kisli#365)

prevWordIsEncoded remained set after a plain word, so the space
before the next encoded-word was also encoded and decoded as two
spaces.
A fold before an encoded-word stands for its leading space just like a
separating space. An empty word writes nothing and keeps the state.
…ded-word (kisli#365)

A separator was written despite leading whitespace, and it was not
counted in the line length.
…li#365)

A name containing '"' was written unquoted, and a '\' in a quoted name
was read back as an escape. Both have to be quoted pairs.
…isli#365)

A name which did not fit on the line lost its quotes, and a comma in it
then split the mailbox in two. A quoted-string may be folded before
whitespace, and unfolding restores it.
…pace run (kisli#365)

Some parsers take backslash-newline as a continuation or collapse the
white-space after a fold. Prefer a single space, else the last one of a
run, else a tab, and fold after a backslash only if there is no other
fold point.
A fold before "<addr>" was followed by another space, and a bare address
was folded even if it did not fit on the new line either. The column
after that fold was counted as 3 instead of 1.
…lists (kisli#365)

", " was written before the next address folded, leaving white-space at
the end of the line and the address split across two lines. The same
for the mailboxes of a group.
…isli#365)

A local part of 75 chars or more was encoded and folded like text, which
RFC 2047 §5 forbids and which split the address. Anything else than
printable ASCII, e.g. ISO-2022-JP escape sequences, is written as a
single encoded-word.
…sli#365)

The space was written before the next id folded, leaving whitespace at
the end of a line.
…kisli#365)

A '(' in a quoted display name opened a comment which never ended, and
the following commas no longer split the list. The same for a '"' in a
comment.
…-word (kisli#365)

Only a leading space was replaced by the separator after an unencoded
word, so a tab was encoded and a space written before it.
@grammmike
grammmike force-pushed the rfc5322-folding branch 2 times, most recently from 2f2f654 to fd99ad7 Compare October 24, 2026 22:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant