struct tws *tws) {
char utc_indicator;
int form_1 = 0;
- int items_matched =
+ int items_matched;
+
+ memset(tws, 0, sizeof *tws);
+ items_matched =
sscanf (datetime, "%4d%2d%2dT%2d%2d%2d%c",
&tws->tw_year, &tws->tw_mon, &tws->tw_mday,
&tws->tw_hour, &tws->tw_min, &tws->tw_sec,
form_1 = 1;
}
- if (items_matched >= 6) {
+ /* items_matched of 3 is for, e.g., 20151230. Assume that means
+ the entire day. The time fields of the tws struct were
+ initialized to 0 by the memset() above. */
+ if (items_matched >= 6 || items_matched == 3) {
int offset = atoi (zone ? zone : "0");
/* struct tws defines tw_mon over [0, 11]. */
--tws->tw_mon;
+ /* Fill out rest of tws, i.e., its tw_wday and tw_flags. */
set_dotw (tws);
/* set_dotw() sets TW_SIMP. Replace that with TW_SEXP so that
dasctime() outputs the dotw before the date instead of after. */
in_daylight = 1;
params = &timezone->daylight_params;
} else if (! strcasecmp ("TZID", node->name)) {
- timezone->tzid = strdup (node->value);
+ /* See comment below in format_datetime() about removing any enclosing quotes from a
+ timezone identifier. */
+ char *buf = mh_xmalloc(strlen(node->value) + 1);
+ unquote_string(node->value, buf);
+ timezone->tzid = buf;
}
} else {
if (! strcasecmp ("BEGIN", node->name) &&
unsigned int year) {
time_t clock = 0;
- if (nmh_strcasestr (rrule, "FREQ=YEARLY;INTERVAL=1")) {
+ if (nmh_strcasestr (rrule, "FREQ=YEARLY;INTERVAL=1") ||
+ (nmh_strcasestr (rrule, "FREQ=YEARLY") && nmh_strcasestr(rrule, "INTERVAL") == NULL)) {
struct tws *tws;
const char *cp;
int wday = -1, month = -1;
/* Extract the timezone, if specified (RFC 5545 Sec. 3.3.5 Form #3). */
for (p = node->params; p && p->param_name; p = p->next) {
if (! strcasecmp (p->param_name, "TZID") && p->values) {
- dt_timezone = p->values->value;
+ /* Remove any enclosing quotes from the timezone identifier. I don't believe that it's
+ legal for it to be quoted, according to RFC 5545 ยง 3.2.19:
+ tzidparam = "TZID" "=" [tzidprefix] paramtext
+ tzidprefix = "/"
+ where paramtext includes SAFE-CHAR, which specifically excludes DQUOTE. But we'll
+ be generous and strip quotes. */
+ char *buf = mh_xmalloc(strlen(p->values->value) + 1);
+ unquote_string(p->values->value, buf);
+ dt_timezone = buf;
break;
}
}
if (tz->tzid && ! strcasecmp (dt_timezone, tz->tzid)) { break; }
}
- if (! tz) {
+ if (tz) {
+ free(dt_timezone);
+ } else {
advise (NULL, "did not find VTIMEZONE section for %s", dt_timezone);
+ free(dt_timezone);
return NULL;
}