@@ -164,7 +164,7 @@ static bool oxcical_parse_vtsubcomponent(const ical_component &sub,
164164 return true ;
165165}
166166
167- static bool oxcical_parse_tzdefinition (const ical_component &vt,
167+ static bool oxcical_tzcom_to_def (const ical_component &vt,
168168 TIMEZONEDEFINITION *ptz_definition)
169169{
170170 int i;
@@ -281,8 +281,7 @@ static void oxcical_convert_to_tzstruct(
281281 ptz_struct->daylightyear = ptz_struct->daylightdate .year ;
282282}
283283
284- static bool oxcical_tzdefinition_to_binary (
285- TIMEZONEDEFINITION *ptz_definition,
284+ static bool oxcical_tzdefinition_to_binary (const TIMEZONEDEFINITION *ptz_definition,
286285 uint16_t tzrule_flags, BINARY *pbin)
287286{
288287 EXT_PUSH ext_push;
@@ -637,16 +636,30 @@ static const ical_component *oxcical_find_vtimezone(const ical &pical, const cha
637636 return nullptr ;
638637}
639638
639+ static bool oxcical_take_tzbin (bool b_dtstart, const BINARY &tmp_bin,
640+ namemap &phash, uint16_t *plast_propid, MESSAGE_CONTENT *pmsg)
641+ {
642+ PROPERTY_NAME propname = {MNID_ID, PSETID_Appointment, b_dtstart ?
643+ PidLidAppointmentTimeZoneDefinitionStartDisplay :
644+ PidLidAppointmentTimeZoneDefinitionEndDisplay};
645+ if (namemap_add (phash, *plast_propid, std::move (propname)) != 0 )
646+ return false ;
647+ if (pmsg->proplist .set (PROP_TAG (PT_BINARY, *plast_propid), &tmp_bin) != ecSuccess)
648+ return false ;
649+ (*plast_propid) ++;
650+ return true ;
651+ }
652+
640653static bool oxcical_parse_tzdisplay (bool b_dtstart, const ical_component &tzcom,
641654 namemap &phash, uint16_t *plast_propid, MESSAGE_CONTENT *pmsg)
642655{
643- BINARY tmp_bin;
644- TIMEZONEDEFINITION tz_definition;
645656 TZRULE rules_buff[MAX_TZRULE_NUMBER];
657+ TIMEZONEDEFINITION tz_definition;
658+ BINARY tmp_bin;
646659 uint8_t bin_buff[MAX_TZDEFINITION_LENGTH];
647660
648661 tz_definition.prules = rules_buff;
649- if (!oxcical_parse_tzdefinition (tzcom, &tz_definition))
662+ if (!oxcical_tzcom_to_def (tzcom, &tz_definition))
650663 return false ;
651664 if (tz_definition.crules == 0 ) {
652665 mlog (LV_DEBUG, " Rejecting conversion of iCal to MAPI object: no sensible TZ rules found (e.g. RFC 5545 §3.6.5 VTIMEZONE without STANDARD/DAYLIGHT not permitted)" );
@@ -657,15 +670,7 @@ static bool oxcical_parse_tzdisplay(bool b_dtstart, const ical_component &tzcom,
657670 if (!oxcical_tzdefinition_to_binary (&tz_definition,
658671 TZRULE_FLAG_EFFECTIVE_TZREG, &tmp_bin))
659672 return false ;
660- PROPERTY_NAME propname = {MNID_ID, PSETID_Appointment, b_dtstart ?
661- PidLidAppointmentTimeZoneDefinitionStartDisplay :
662- PidLidAppointmentTimeZoneDefinitionEndDisplay};
663- if (namemap_add (phash, *plast_propid, std::move (propname)) != 0 )
664- return false ;
665- if (pmsg->proplist .set (PROP_TAG (PT_BINARY, *plast_propid), &tmp_bin) != ecSuccess)
666- return false ;
667- (*plast_propid) ++;
668- return true ;
673+ return oxcical_take_tzbin (b_dtstart, tmp_bin, phash, plast_propid, pmsg);
669674}
670675
671676static bool oxcical_parse_recurring_timezone (const ical_component &tzcom,
@@ -679,7 +684,7 @@ static bool oxcical_parse_recurring_timezone(const ical_component &tzcom,
679684 uint8_t bin_buff[MAX_TZDEFINITION_LENGTH];
680685
681686 tz_definition.prules = rules_buff;
682- if (!oxcical_parse_tzdefinition (tzcom, &tz_definition))
687+ if (!oxcical_tzcom_to_def (tzcom, &tz_definition))
683688 return false ;
684689 auto piline = tzcom.get_line (" TZID" );
685690 if (piline == nullptr )
@@ -2054,13 +2059,32 @@ static const char *oxcical_import_internal(const char *str_zone, const char *met
20542059 const ical_component *ptz_component = nullptr ;
20552060 if (ptzid != nullptr ) {
20562061 ptz_component = oxcical_find_vtimezone (pical, ptzid);
2057- if (ptz_component == nullptr ) {
2058- mlog (LV_ERR, " E-2070: %s: timezone \" %s\" not found" , __func__, znul (ptzid));
2059- return " Used timezone was not declared" ;
2062+ if (ptz_component != nullptr ) {
2063+ if (!oxcical_parse_tzdisplay (true , *ptz_component, phash,
2064+ &last_propid, pmsg))
2065+ return " E-2195: oxcical_parse_tzdisplay returned an unspecified error" ;
2066+ } else {
2067+ /*
2068+ * As per RFC 5545 §3.2.19, """An individual "VTIMEZONE" calendar
2069+ * component MUST be specified for each unique "TZID" parameter
2070+ * value""".
2071+ */
2072+
2073+ /* Some final heroic efforts */
2074+ auto def = ianatz_to_tzdef (ptzid);
2075+ if (def == nullptr )
2076+ def = wintz_to_tzdef (ptzid);
2077+ if (def == nullptr ) {
2078+ mlog (LV_ERR, " E-2070: %s: timezone \" %s\" not found" , __func__, ptzid);
2079+ return " Used timezone was not declared" ;
2080+ }
2081+ mlog (LV_DEBUG, " D-5324: synthesized data for TZID \" %s\" from internal db" , ptzid);
2082+ BINARY bin;
2083+ bin.cb = def->size ();
2084+ bin.pc = deconst (def->data ());
2085+ if (!oxcical_take_tzbin (true , bin, phash, &last_propid, pmsg))
2086+ return " E-5323: oxcical_parse_tzdef returned an unspecified error" ;
20602087 }
2061- if (!oxcical_parse_tzdisplay (true , *ptz_component, phash,
2062- &last_propid, pmsg))
2063- return " E-2195: oxcical_parse_tzdisplay returned an unspecified error" ;
20642088 }
20652089
20662090 time_t start_time = 0 , end_time = 0 ;
0 commit comments