Skip to content

Don't mangle a vCard timestamp given in the extended format; fixes #1028 - #1029

Open
mkmelin wants to merge 1 commit into
kewisch:mainfrom
mkmelin:rev-fix
Open

mkmelin wants to merge 1 commit into
kewisch:mainfrom
mkmelin:rev-fix

Conversation

@mkmelin

@mkmelin mkmelin commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

The vcard4 design set aliases the timestamp value type to iCalendar's date-time, whose fromICAL/toICAL insert and remove the separators at fixed offsets because iCalendar only ever uses the basic format. RFC 6350 allows only the basic format for a timestamp as well, but the extended format is widely used in the wild, and slicing it at those offsets produced garbage: parsing REV:1995-10-31T22:27:10Z gave the jCal value 1995--1-0-T1T:22::2, stringified back as REV:1995-10-T1T22:2.

Delegate to the date-and-or-time conversions, which probe the value length instead of assuming offsets, so both formats are read and a UTC offset survives. Output stays in the basic format. decorate/undecorate are kept as they were, so getFirstValue() on REV still returns an ICAL.Time.

@kewisch

kewisch commented Sep 17, 2026

Copy link
Copy Markdown
Owner

There is a lenient switch somewhere that should be used for more lenient parsing. The idea is that if you prefer strict validation (e.g. because you want to verify if it is correct) you can use the default, but if you want to accept usage in the wild then lenient mode is for you.

It sounds like that would be useful here?

I think the other issue, probably outside of this PR, is that there isn't good validation in date parsing (I think back then done in the name of performance), which leads to the 1995--1-0-... problem. It should be rejected rather than producing incorrect results.

@mkmelin

mkmelin commented Sep 24, 2026

Copy link
Copy Markdown
Contributor Author

Good call. The extended format is now only accepted when design.strict is false. Looks like we need to set that in Thunderbird though (for address book).

I can open another issue for rejecting malformed date/time values

…wisch#1028

The vcard4 design set aliases the timestamp value type to iCalendar's
date-time, whose conversions insert and remove the separators at fixed offsets.
That drops the zone from a conforming basic-format value carrying a numeric
utc-offset (19951031T222710+0200 parsed to 1995-10-31T22:27:10), and it mangles
a value in the extended format, which RFC 6350 does not allow but which is
widely used: REV:1995-10-31T22:27:10Z parsed to 1995--1-0-T1T:22::2 and was
stringified back as REV:1995-10-T1T22:2.

Delegate to the date-and-or-time conversions, which probe the value instead of
assuming offsets. toICAL always uses them, since a jCal value is in the
extended format by definition. fromICAL uses them for a conforming value in
either mode, and for the extended format only in lenient mode, leaving strict
mode's handling of malformed input alone. decorate/undecorate are unchanged, so
getFirstValue() on REV still returns an ICAL.Time.

This branch has not been deployed

No deployments
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.

2 participants