Conversation
|
There is a 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. |
|
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.
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.