Summary
The ICS feed served for a shared/public Proton Calendar link (PRODID:-//Proton AG//ProtonCalendar 1.0.0//EN) folds long content lines at 75 octets per RFC 5545. When the fold boundary lands on a space inside the text, the exporter sometimes uses that content space as the fold marker instead of inserting an additional one. RFC 5545 §3.1 unfolding (remove CRLF plus one whitespace) then deletes a character that belongs to the content.
The folding also differs between requests for identical event content, so consumers see the text flip between correct and corrupted.
Observed bytes
A DESCRIPTION containing the text Panel talk "Jazz für alle?" was served in two variants, fetched ~10 minutes apart with no event modification in between ($ marks CRLF, · marks a space):
Fetch A (correct — content space kept at the end of the folded line, marker space added):
DESCRIPTION:url: ...\nPanel talk "Jazz für·$
·alle?" + Fiona Grond & Luca Zambito + ...$
Fetch B (broken — the content space was moved to the continuation line, where it doubles as the fold marker):
DESCRIPTION:url: ...\nPanel talk "Jazz für$
·alle?" + Fiona Grond & Luca Zambito + ...$
Compliant unfolding of Fetch B yields Panel talk "Jazz füralle?".
Supporting statistics
Fold-line octet lengths across the same feed (~6700 VEVENTs, ~2360 folds), measured on the two fetches:
- Fetch A: 75 octets ×2362, 74 ×10, 73 ×2 (the short ones are legitimate multi-byte UTF-8 characters that would straddle the 75-octet boundary)
- Fetch B: 75 ×2225, 74 ×127, 73 ×4, 72 ×1
The ~120 additional short folds in Fetch B are exactly the cases where the next character would still have fit within 75 octets — i.e. the fold was taken early on a space, consuming it. Affected spots in Fetch B include Jazz für|alle? and Hennicker-Schmidt| – Anton Kaun (space before an en dash).
Expected
Folding must be content-preserving: the inserted CRLF + single whitespace must be additional bytes, so that unfolding reproduces the original text exactly, regardless of where the boundary falls. Identical content should also fold identically across requests.
Impact
Any RFC-compliant consumer (tested with Python icalendar, but this is inherent to the spec, not a parser quirk) loses spaces from event descriptions, summaries, and locations at unpredictable positions that change between fetches. The information is unrecoverable for the consumer in the general case.
Environment
- Shared calendar URL export (
calendar.proton.me/api/calendar/v1/url/.../calendar.ics)
PRODID:-//Proton AG//ProtonCalendar 1.0.0//EN, VERSION:2.0
- Observed 2026-06-12; reproducible by re-fetching a feed with long description lines until the fold boundary shifts onto a space
Summary
The ICS feed served for a shared/public Proton Calendar link (
PRODID:-//Proton AG//ProtonCalendar 1.0.0//EN) folds long content lines at 75 octets per RFC 5545. When the fold boundary lands on a space inside the text, the exporter sometimes uses that content space as the fold marker instead of inserting an additional one. RFC 5545 §3.1 unfolding (remove CRLF plus one whitespace) then deletes a character that belongs to the content.The folding also differs between requests for identical event content, so consumers see the text flip between correct and corrupted.
Observed bytes
A
DESCRIPTIONcontaining the textPanel talk "Jazz für alle?"was served in two variants, fetched ~10 minutes apart with no event modification in between ($marks CRLF,·marks a space):Fetch A (correct — content space kept at the end of the folded line, marker space added):
Fetch B (broken — the content space was moved to the continuation line, where it doubles as the fold marker):
Compliant unfolding of Fetch B yields
Panel talk "Jazz füralle?".Supporting statistics
Fold-line octet lengths across the same feed (~6700 VEVENTs, ~2360 folds), measured on the two fetches:
The ~120 additional short folds in Fetch B are exactly the cases where the next character would still have fit within 75 octets — i.e. the fold was taken early on a space, consuming it. Affected spots in Fetch B include
Jazz für|alle?andHennicker-Schmidt| – Anton Kaun(space before an en dash).Expected
Folding must be content-preserving: the inserted CRLF + single whitespace must be additional bytes, so that unfolding reproduces the original text exactly, regardless of where the boundary falls. Identical content should also fold identically across requests.
Impact
Any RFC-compliant consumer (tested with Python
icalendar, but this is inherent to the spec, not a parser quirk) loses spaces from event descriptions, summaries, and locations at unpredictable positions that change between fetches. The information is unrecoverable for the consumer in the general case.Environment
calendar.proton.me/api/calendar/v1/url/.../calendar.ics)PRODID:-//Proton AG//ProtonCalendar 1.0.0//EN,VERSION:2.0