summaryrefslogtreecommitdiff
path: root/src/libical/icalcomponent.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libical/icalcomponent.c')
-rw-r--r--src/libical/icalcomponent.c188
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);
}
}