1 /*======================================================================
2  FILE: icalattach-leak.c
3 
4  Copyright (C) 2019 Red Hat, Inc. <www.redhat.com>
5 
6  This library is free software; you can redistribute it and/or modify
7  it under the terms of either:
8 
9     The LGPL as published by the Free Software Foundation, version
10     2.1, available at: https://www.gnu.org/licenses/lgpl-2.1.html
11 
12  Or:
13 
14     The Mozilla Public License Version 2.0. You may obtain a copy of
15     the License at https://www.mozilla.org/MPL/
16 
17  The Initial Developer of the Original Code is Milan Crha
18 ======================================================================*/
19 
20 /*
21  * Program for testing ICalAttach memory handling.
22  */
23 
24 #include <stdio.h>
25 
26 #define LIBICAL_GLIB_UNSTABLE_API
27 #include "libical-glib/libical-glib.h"
28 #undef LIBICAL_GLIB_UNSTABLE_API
29 
get_attachments(ICalComponent * comp)30 static GSList *get_attachments(ICalComponent *comp)
31 {
32     ICalProperty *prop;
33     GSList *attaches = NULL;
34 
35     for (prop = i_cal_component_get_first_property(comp, I_CAL_ATTACH_PROPERTY);
36          prop;
37          g_object_unref(prop),
38          prop = i_cal_component_get_next_property(comp, I_CAL_ATTACH_PROPERTY)) {
39         attaches = g_slist_prepend(attaches, i_cal_property_get_attach(prop));
40     }
41 
42     return attaches;
43 }
44 
remove_all_attachments(ICalComponent * comp)45 static void remove_all_attachments(ICalComponent *comp)
46 {
47     GSList *to_remove = NULL, *link;
48     ICalProperty *prop;
49 
50     for (prop = i_cal_component_get_first_property(comp, I_CAL_ATTACH_PROPERTY);
51          prop;
52          g_object_unref(prop),
53          prop = i_cal_component_get_next_property(comp, I_CAL_ATTACH_PROPERTY)) {
54         to_remove = g_slist_prepend(to_remove, g_object_ref(prop));
55     }
56 
57     for (link = to_remove; link; link = g_slist_next(link)) {
58         prop = link->data;
59 
60         i_cal_component_remove_property(comp, prop);
61     }
62 
63     g_slist_free_full(to_remove, g_object_unref);
64 }
65 
set_attachments(ICalComponent * comp,GSList * attaches)66 static void set_attachments(ICalComponent *comp, GSList *attaches)
67 {
68     GSList *link;
69 
70     remove_all_attachments (comp);
71 
72     for (link = attaches; link; link = g_slist_next (link)) {
73         ICalAttach *attach = link->data;
74 
75         i_cal_component_take_property(comp, i_cal_property_new_attach (attach));
76     }
77 }
78 
main(void)79 int main (void)
80 {
81     ICalComponent *comp;
82     GSList *attaches;
83 
84     comp = i_cal_component_new_from_string(
85         "BEGIN:VEVENT\r\n"
86         "UID:123\r\n"
87         "ATTACH:file:///tmp/f1.txt\r\n"
88         "ATTACH:file:///tmp/f2.txt\r\n"
89         "END:VEVENT\r\n"
90     );
91 
92     attaches = get_attachments(comp);
93     printf("%s: 1st: has %d attachments\n", __FUNCTION__, g_slist_length(attaches));
94     set_attachments(comp, attaches);
95     g_slist_free_full(attaches, g_object_unref);
96 
97     attaches = get_attachments(comp);
98     printf("%s: 2nd: has %d attachments\n", __FUNCTION__, g_slist_length(attaches));
99     g_slist_free_full(attaches, g_object_unref);
100 
101     g_object_unref(comp);
102 
103     return 0;
104 }
105