diff options
Diffstat (limited to 'src/libical/icalcomponent.c')
-rw-r--r-- | src/libical/icalcomponent.c | 188 |
1 files changed, 110 insertions, 78 deletions
diff --git a/src/libical/icalcomponent.c b/src/libical/icalcomponent.c index 4b01c7e..ed08546 100644 --- a/src/libical/icalcomponent.c +++ b/src/libical/icalcomponent.c @@ -47,6 +47,11 @@ #include <string.h> /* for strdup */ #include <limits.h> /* for INT_MAX */ +#ifdef _MSC_VER +#define snprintf _snprintf +#define strncasecmp strnicmp +#endif + struct icalcomponent_impl { char id[5]; @@ -81,7 +86,7 @@ static void icalcomponent_handle_conflicting_vtimezones (icalcomponent *comp, icalproperty *tzid_prop, const char *tzid, icalarray *tzids_to_rename); -static unsigned int icalcomponent_get_tzid_prefix_len (const char *tzid); +static size_t icalcomponent_get_tzid_prefix_len (const char *tzid); static void icalcomponent_rename_tzids(icalcomponent* comp, icalarray* rename_table); static void icalcomponent_rename_tzids_callback(icalparameter *param, @@ -90,6 +95,8 @@ static int icalcomponent_compare_vtimezones (icalcomponent *vtimezone1, icalcomponent *vtimezone2); static int icalcomponent_compare_timezone_fn (const void *elem1, const void *elem2); +static struct icaltimetype +icalcomponent_get_datetime(icalcomponent *comp, icalproperty *prop); void icalcomponent_add_children(icalcomponent *impl, va_list args) @@ -245,24 +252,22 @@ icalcomponent_free (icalcomponent* c) if(c != 0 ){ - if ( c->properties != 0 ) - { - while( (prop=pvl_pop(c->properties)) != 0){ - assert(prop != 0); - icalproperty_set_parent(prop,0); - icalproperty_free(prop); - } - pvl_free(c->properties); - } + if ( c->properties != 0 ) + { + while( (prop=pvl_pop(c->properties)) != 0){ + icalproperty_set_parent(prop,0); + icalproperty_free(prop); + } + pvl_free(c->properties); + } - while( (comp=pvl_data(pvl_head(c->components))) != 0){ - assert(comp!=0); - icalcomponent_remove_component(c,comp); - icalcomponent_free(comp); - } + while( (comp=pvl_data(pvl_head(c->components))) != 0){ + icalcomponent_remove_component(c,comp); + icalcomponent_free(comp); + } - pvl_free(c->components); + pvl_free(c->components); if (c->x_name != 0) { free(c->x_name); @@ -312,9 +317,6 @@ icalcomponent_as_ical_string_r (icalcomponent* impl) const char* kind_string; - buf = icalmemory_new_buffer(buf_size); - buf_ptr = buf; - icalerror_check_arg_rz( (impl!=0), "component"); icalerror_check_arg_rz( (kind!=ICAL_NO_COMPONENT), "component kind is ICAL_NO_COMPONENT"); @@ -326,6 +328,9 @@ icalcomponent_as_ical_string_r (icalcomponent* impl) icalerror_check_arg_rz( (kind_string!=0),"Unknown kind of component"); + buf = icalmemory_new_buffer(buf_size); + buf_ptr = buf; + icalmemory_append_string(&buf, &buf_ptr, &buf_size, "BEGIN:"); icalmemory_append_string(&buf, &buf_ptr, &buf_size, kind_string); icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline); @@ -390,7 +395,6 @@ icalcomponent_isa (const icalcomponent* component) { return component->kind; } - return ICAL_NO_COMPONENT; } @@ -432,8 +436,13 @@ icalcomponent_remove_property (icalcomponent* component, icalproperty* property) icalerror_check_arg_rv( (component!=0), "component"); icalerror_check_arg_rv( (property!=0), "property"); +#ifdef ICAL_REMOVE_NONMEMBER_COMPONENT_IS_ERROR icalerror_assert( (icalproperty_get_parent(property)),"The property is not a member of a component"); - +#else + if(icalproperty_get_parent(property) == 0){ + return; + } +#endif for( itr = pvl_head(component->properties); itr != 0; @@ -481,7 +490,7 @@ icalproperty* icalcomponent_get_current_property (icalcomponent* component) { icalerror_check_arg_rz( (component!=0),"component"); - if ((component->property_iterator==0)){ + if (component->property_iterator==0){ return 0; } @@ -847,23 +856,27 @@ int icalproperty_recurrence_is_excluded(icalcomponent *comp, struct icaltimetype *dtstart, struct icaltimetype *recurtime) { icalproperty *exdate, *exrule; - pvl_elem property_iterator = comp->property_iterator; + pvl_elem property_iterator; if (comp == NULL || dtstart == NULL || recurtime == NULL || icaltime_is_null_time(*recurtime)) /* BAD DATA */ - return 1; + return 1; + + property_iterator = comp->property_iterator; /** first test against the exdate values **/ for (exdate = icalcomponent_get_first_property(comp,ICAL_EXDATE_PROPERTY); exdate != NULL; exdate = icalcomponent_get_next_property(comp,ICAL_EXDATE_PROPERTY)) { - struct icaltimetype exdatetime = icalproperty_get_exdate(exdate); + struct icaltimetype exdatetime = icalcomponent_get_datetime(comp, exdate); - if (icaltime_compare(*recurtime, exdatetime) == 0) { + if ((icaltime_is_date(exdatetime) + && icaltime_compare_date_only(*recurtime, exdatetime) == 0) || + (icaltime_compare(*recurtime, exdatetime) == 0)) { /** MATCHED **/ comp->property_iterator = property_iterator; @@ -880,7 +893,7 @@ int icalproperty_recurrence_is_excluded(icalcomponent *comp, icalrecur_iterator *exrule_itr = icalrecur_iterator_new(recur, *dtstart); struct icaltimetype exrule_time; - while (1) { + while (exrule_itr) { int result; exrule_time = icalrecur_iterator_next(exrule_itr); @@ -988,7 +1001,7 @@ void icalcomponent_foreach_recurrence(icalcomponent* comp, struct icaltimetype dtstart, dtend; icaltime_span recurspan, basespan, limit_span; time_t limit_start, limit_end; - int dtduration; + time_t dtduration; icalproperty *rrule, *rdate; struct icaldurationtype dur; pvl_elem property_iterator; /* for saving the iterator */ @@ -1042,16 +1055,22 @@ void icalcomponent_foreach_recurrence(icalcomponent* comp, struct icalrecurrencetype recur = icalproperty_get_rrule(rrule); icalrecur_iterator *rrule_itr = icalrecur_iterator_new(recur, dtstart); - struct icaltimetype rrule_time = icalrecur_iterator_next(rrule_itr); + struct icaltimetype rrule_time; + if(rrule_itr) + rrule_time = icalrecur_iterator_next(rrule_itr); /** note that icalrecur_iterator_next always returns dtstart the first time.. **/ - while (1) { + while (rrule_itr) { rrule_time = icalrecur_iterator_next(rrule_itr); if (icaltime_is_null_time(rrule_time)) break; + /* if we have iterated past end time, then no need to check any further */ + if (icaltime_compare(rrule_time, end) > 0) + break; + dur = icaltime_subtract(rrule_time, dtstart); recurspan.start = basespan.start + icaldurationtype_as_int(dur); @@ -1097,6 +1116,7 @@ void icalcomponent_foreach_recurrence(icalcomponent* comp, if (!icalproperty_recurrence_is_excluded(comp, &dtstart, &rdate_period.time)) { /** call callback action **/ + if (icaltime_span_overlaps(&recurspan, &limit_span)) (*callback) (comp, &recurspan, callback_data); } comp->property_iterator = property_iterator; @@ -1166,6 +1186,8 @@ void icalcomponent_strip_errors(icalcomponent* component) if(icalproperty_isa(p) == ICAL_XLICERROR_PROPERTY) { icalcomponent_remove_property(component,p); + icalproperty_free(p); + p = NULL; } } @@ -1233,6 +1255,8 @@ void icalcomponent_convert_errors(icalcomponent* component) icalproperty_new_requeststatus(rst)); icalcomponent_remove_property(component,p); + icalproperty_free(p); + p = NULL; } } } @@ -1611,17 +1635,20 @@ struct icaltimetype icalcomponent_get_dtend(icalcomponent* comp) struct icaltimetype ret = icaltime_null_time(); if ( end_prop != 0) { - ret = icalcomponent_get_datetime(comp, end_prop); - } else if ( dur_prop != 0) { - - struct icaltimetype start = - icalcomponent_get_dtstart(inner); - struct icaldurationtype duration = - icalproperty_get_duration(dur_prop); + ret = icalcomponent_get_datetime(comp, end_prop); + } else if ( dur_prop != 0) { - struct icaltimetype end = icaltime_add(start,duration); + struct icaltimetype start = icalcomponent_get_dtstart(inner); + struct icaldurationtype duration; + + //extra check to prevent empty durations from crashing + if (icalproperty_get_value(dur_prop)) { + duration = icalproperty_get_duration(dur_prop); + } else { + duration = icaldurationtype_null_duration(); + } - ret = end; + ret = icaltime_add(start,duration); } return ret; @@ -2027,51 +2054,51 @@ enum icalproperty_status icalcomponent_get_status(icalcomponent* comp){ return icalproperty_get_status(prop); } -icalcomponent* icalcomponent_new_vcalendar() +icalcomponent* icalcomponent_new_vcalendar(void) { return icalcomponent_new(ICAL_VCALENDAR_COMPONENT); } -icalcomponent* icalcomponent_new_vevent() +icalcomponent* icalcomponent_new_vevent(void) { return icalcomponent_new(ICAL_VEVENT_COMPONENT); } -icalcomponent* icalcomponent_new_vtodo() +icalcomponent* icalcomponent_new_vtodo(void) { return icalcomponent_new(ICAL_VTODO_COMPONENT); } -icalcomponent* icalcomponent_new_vjournal() +icalcomponent* icalcomponent_new_vjournal(void) { return icalcomponent_new(ICAL_VJOURNAL_COMPONENT); } -icalcomponent* icalcomponent_new_valarm() +icalcomponent* icalcomponent_new_valarm(void) { return icalcomponent_new(ICAL_VALARM_COMPONENT); } -icalcomponent* icalcomponent_new_vfreebusy() +icalcomponent* icalcomponent_new_vfreebusy(void) { return icalcomponent_new(ICAL_VFREEBUSY_COMPONENT); } -icalcomponent* icalcomponent_new_vtimezone() +icalcomponent* icalcomponent_new_vtimezone(void) { return icalcomponent_new(ICAL_VTIMEZONE_COMPONENT); } -icalcomponent* icalcomponent_new_xstandard() +icalcomponent* icalcomponent_new_xstandard(void) { return icalcomponent_new(ICAL_XSTANDARD_COMPONENT); } -icalcomponent* icalcomponent_new_xdaylight() +icalcomponent* icalcomponent_new_xdaylight(void) { return icalcomponent_new(ICAL_XDAYLIGHT_COMPONENT); } -icalcomponent* icalcomponent_new_vagenda() +icalcomponent* icalcomponent_new_vagenda(void) { return icalcomponent_new(ICAL_VAGENDA_COMPONENT); } -icalcomponent* icalcomponent_new_vquery() +icalcomponent* icalcomponent_new_vquery(void) { return icalcomponent_new(ICAL_VQUERY_COMPONENT); } -icalcomponent* icalcomponent_new_vreply() +icalcomponent* icalcomponent_new_vreply(void) { return icalcomponent_new(ICAL_VREPLY_COMPONENT); } @@ -2122,9 +2149,8 @@ void icalcomponent_merge_component(icalcomponent* comp, for (i = 0; i < tzids_to_rename->num_elements; i++) { free (icalarray_element_at (tzids_to_rename, i)); } - icalarray_free (tzids_to_rename); } - + icalarray_free (tzids_to_rename); /* Now move all the components from comp_to_merge to comp, excluding VTIMEZONE components. */ subcomp = icalcomponent_get_first_component (comp_to_merge, @@ -2209,7 +2235,7 @@ icalcomponent_handle_conflicting_vtimezones (icalcomponent *comp, icalarray *tzids_to_rename) { int i, suffix, max_suffix = 0, num_elements; - unsigned int tzid_len; + size_t tzid_len; char *tzid_copy, *new_tzid, suffix_buf[32]; (void)tzid_prop; /* hack to stop unused variable warning */ @@ -2228,7 +2254,7 @@ icalcomponent_handle_conflicting_vtimezones (icalcomponent *comp, icaltimezone *zone; const char *existing_tzid; const char *existing_tzid_copy; - unsigned int existing_tzid_len; + size_t existing_tzid_len; zone = icalarray_element_at (comp->timezones, i); existing_tzid = icaltimezone_get_tzid (zone); @@ -2245,11 +2271,17 @@ icalcomponent_handle_conflicting_vtimezones (icalcomponent *comp, /* The VTIMEZONEs match, so we can use the existing VTIMEZONE. But we have to rename TZIDs to this TZID. */ tzid_copy = strdup (tzid); + if(!tzid_copy) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return; + } existing_tzid_copy = strdup (existing_tzid); - if (!tzid_copy || !existing_tzid_copy) { + if (!existing_tzid_copy) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); + free(tzid_copy); } else { icalarray_append (tzids_to_rename, tzid_copy); + free(tzid_copy); icalarray_append (tzids_to_rename, existing_tzid_copy); } return; @@ -2268,10 +2300,16 @@ icalcomponent_handle_conflicting_vtimezones (icalcomponent *comp, /* We didn't find a VTIMEZONE that matched, so we have to rename the TZID, using the maximum numerical suffix found + 1. */ tzid_copy = strdup (tzid); + if(!tzid_copy) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return; + } + snprintf (suffix_buf, sizeof(suffix_buf), "%i", max_suffix + 1); new_tzid = malloc (tzid_len + strlen (suffix_buf) + 1); - if (!new_tzid || !tzid_copy) { + if (!new_tzid) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); + free(tzid_copy); return; } @@ -2279,13 +2317,15 @@ icalcomponent_handle_conflicting_vtimezones (icalcomponent *comp, strcpy (new_tzid + tzid_len, suffix_buf); icalarray_append (tzids_to_rename, tzid_copy); icalarray_append (tzids_to_rename, new_tzid); + free(tzid_copy); + free(new_tzid); } /* Returns the length of the TZID, without any trailing digits. */ -static unsigned int icalcomponent_get_tzid_prefix_len (const char *tzid) +static size_t icalcomponent_get_tzid_prefix_len (const char *tzid) { - int len; + size_t len; const char *p; len = strlen (tzid); @@ -2400,13 +2440,15 @@ icaltimezone* icalcomponent_get_timezone(icalcomponent* comp, const char *tzid) middle = (lower + upper) >> 1; zone = icalarray_element_at (comp->timezones, middle); zone_tzid = icaltimezone_get_tzid (zone); - cmp = strcmp (tzid, zone_tzid); - if (cmp == 0) - return zone; - else if (cmp < 0) - upper = middle; - else - lower = middle + 1; + if (zone_tzid != NULL) { + cmp = strcmp (tzid, zone_tzid); + if (cmp == 0) + return zone; + else if (cmp < 0) + upper = middle; + else + lower = middle + 1; + } } return NULL; @@ -2569,9 +2611,7 @@ struct icaltimetype icalcomponent_get_due(icalcomponent* comp) icalproperty *dur_prop = icalcomponent_get_first_property(inner, ICAL_DURATION_PROPERTY); - if( due_prop == 0 && dur_prop == 0){ - return icaltime_null_time(); - } else if ( due_prop != 0) { + if ( due_prop != 0) { return icalproperty_get_due(due_prop); } else if ( dur_prop != 0) { @@ -2584,13 +2624,8 @@ struct icaltimetype icalcomponent_get_due(icalcomponent* comp) return due; - } else { - /* Error, both duration and due have been specified */ - icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); - return icaltime_null_time(); - } - + return icaltime_null_time(); } /** @brief Set the due date of a VTODO task. @@ -2632,8 +2667,5 @@ void icalcomponent_set_due(icalcomponent* comp, struct icaltimetype v) icalproperty_set_duration(dur_prop,dur); - } else { - /* Error, both duration and due have been specified */ - icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); } } |