You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Vendors the current IANA vCard property and parameter registries with explicit handling declarations and drift/update commands.
Adds bounded, ordered decode and render support for vCard 2.1, 3.0, and 4.0 while preserving groups, source spelling, parameter order and quoting, raw values, repeated properties, and unknown extensions.
Keeps the existing Contact and ParseFile API as a compatible projection over the lossless codec.
Why
Richer person profiles and CardDAV need a standards boundary that can preserve source syntax and data Msgvault does not yet understand. The previous contact projection discarded that information, making future native mapping and round trips lossy.
This is the first focused step in #534. Native profile mapping, resource persistence, and CardDAV serving remain separate follow-up boundaries.
Usage
Run make vcard-registry-check to report upstream registry drift. Run make vcard-registry-update to fetch and atomically write a validated snapshot for review.
Medium-severity vCard compatibility issues should be addressed before merging.
Medium
internal/vcard/legacy.go:58 — Parameterized tel: URIs are normalized incorrectly
Valid URI parameters are included in digit-only normalization. For example, tel:+1-202-555-0123;ext=456 becomes +12025550123456, while phone-context values may be rejected entirely.
Fix: Parse TEL URIs and normalize only the telephone-number component, handling extensions and phone-context separately. Add coverage for parameterized TEL URIs.
internal/vcard/decode.go:105 — Valid legacy-character-set vCards are rejected or decoded incorrectly
Requiring every physical line to be UTF-8 rejects valid vCard 2.1 files declaring character sets such as ISO-8859-1. Quoted-printable values can pass this check but are decoded without applying CHARSET, potentially yielding invalid UTF-8 contact names.
Fix: Honor CHARSET when decoding legacy values and defer validation/transcoding until after transfer decoding. Add literal and quoted-printable non-UTF-8 fixtures.
TEL URI projection now excludes ext from E.164 identity keys and resolves local subscribers with numeric phone-context separately.
Legacy text decoding now applies quoted-printable transfer decoding before the declared CHARSET conversion; literal and quoted-printable ISO-8859-1 vCard 2.1 values are covered.
Medium-severity issues remain in the vCard codec and parser.
Medium
internal/vcard/encode.go:215 — Quoted-printable folding can split an =XX escape immediately after =. During decoding, unfoldLines treats the trailing = as a soft break and removes it, corrupting marshal/decode round trips. Make folding quoted-printable-aware and add a boundary regression test.
internal/vcard/encode.go:201, internal/vcard/decode.go:165 — The decoder accepts non-UTF-8 values with a legacy CHARSET, but the encoder unconditionally rejects the resulting document. Valid vCard 2.1 data such as raw ISO-8859-1 cannot round-trip through the lossless codec. Preserve charset-tagged bytes safely or normalize the value and charset metadata before encoding, with legacy-charset round-trip coverage.
internal/vcard/contentline.go:84 — Parameter-value parsing permits severe memory amplification. A content line near the 16 MiB limit containing millions of comma-separated values can cause splitOutsideQuotes and ParameterValue allocations to consume roughly a gigabyte of memory. Enforce parameter and value-count limits before allocating, preferably with a capped splitter, and consider a total decoded-property/input budget.
Quoted-printable folding now chooses boundaries outside =XX escapes, preventing trailing = from being consumed as a soft break.
Charset-declared legacy bytes accepted by the decoder are preserved by the lossless encoder and can round-trip through folding.
Quote-aware parsing now caps each property at 100 parameters and each parameter at 100 values before allocation amplification; boundary tests cover 100 and 101.
Focused and repository-wide tests, lint, vet, and testify checks pass. The PR remains one commit.
Medium-severity performance and resource-exhaustion risk found in the vCard decoder.
Medium
internal/vcard/decode.go:40 — The decoder buffers the entire input before enforcing MaxCards, allowing oversized documents to consume unbounded memory before rejection. Additionally, repeated string concatenation for folded lines at line 144 can cause quadratic processing time on heavily folded input.
Suggested fix: Stream physical lines through unfolding and card parsing, use a string builder for continuations, and enforce card or total-input limits while reading.
Medium-severity version handling issue found; no material security vulnerabilities identified.
Medium
RFC 6868 decoding applied to pre-4.0 vCards — internal/vcard/contentline.go:79,139
Caret decoding is unconditional, although RFC 6868 applies only to vCard 4.0. In vCard 2.1/3.0, literal sequences such as ^n therefore produce an incorrect Decoded value. Decode and encode parameter values according to the containing card’s version, and add tests covering literal carets in vCard 2.1/3.0 parameters.
Fixed in c50f6e9. RFC 6868 parameter escaping now follows the containing card version: vCard 2.1/3.0 retain literal caret sequences, while 4.0 continues to decode and encode RFC 6868. Added 2.1/3.0 decode and constructed-parameter regression coverage.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
ContactandParseFileAPI as a compatible projection over the lossless codec.Why
Richer person profiles and CardDAV need a standards boundary that can preserve source syntax and data Msgvault does not yet understand. The previous contact projection discarded that information, making future native mapping and round trips lossy.
This is the first focused step in #534. Native profile mapping, resource persistence, and CardDAV serving remain separate follow-up boundaries.
Usage
Run
make vcard-registry-checkto report upstream registry drift. Runmake vcard-registry-updateto fetch and atomically write a validated snapshot for review.