Coverage Report

Created: 2024-09-30 06:41

/src/libical/src/libical/icaltypes.c
Line
Count
Source (jump to first uncovered line)
1
/*======================================================================
2
 FILE: icaltypes.c
3
 CREATOR: eric 16 May 1999
4
5
 SPDX-FileCopyrightText: 2000, Eric Busboom <eric@civicknowledge.com>
6
7
 SPDX-License-Identifier: LGPL-2.1-only OR MPL-2.0
8
9
 ======================================================================*/
10
#ifdef HAVE_CONFIG_H
11
#include <config.h>
12
#endif
13
14
#include "icaltypes.h"
15
#include "icalerror.h"
16
#include "icalmemory.h"
17
18
12.1M
#define TMP_BUF_SIZE 1024
19
20
#if ICAL_SYNC_MODE == ICAL_SYNC_MODE_PTHREAD
21
#include <pthread.h>
22
static pthread_mutex_t unk_token_mutex = PTHREAD_MUTEX_INITIALIZER;
23
#endif
24
#include <ctype.h>
25
static ICAL_GLOBAL_VAR ical_unknown_token_handling unknownTokenHandling = ICAL_TREAT_AS_ERROR;
26
27
int icaltriggertype_is_null_trigger(struct icaltriggertype tr)
28
0
{
29
0
    if (icaltime_is_null_time(tr.time) && icaldurationtype_is_null_duration(tr.duration)) {
30
0
        return 1;
31
0
    }
32
33
0
    return 0;
34
0
}
35
36
int icaltriggertype_is_bad_trigger(struct icaltriggertype tr)
37
0
{
38
0
    if (icaldurationtype_is_bad_duration(tr.duration)) {
39
0
        return 1;
40
0
    }
41
42
0
    return 0;
43
0
}
44
45
struct icaltriggertype icaltriggertype_from_int(const int reltime)
46
0
{
47
0
    struct icaltriggertype tr;
48
49
0
    tr.time = icaltime_null_time();
50
0
    tr.duration = icaldurationtype_from_int(reltime);
51
52
0
    return tr;
53
0
}
54
55
struct icaltriggertype icaltriggertype_from_string(const char *str)
56
0
{
57
0
    struct icaltriggertype tr;
58
0
    icalerrorstate es;
59
0
    icalerrorenum e;
60
61
0
    tr.time = icaltime_null_time();
62
0
    tr.duration = icaldurationtype_from_int(0);
63
64
    /* Suppress errors so a failure in icaltime_from_string() does not cause an abort */
65
0
    es = icalerror_get_error_state(ICAL_MALFORMEDDATA_ERROR);
66
0
    if (str == 0) {
67
0
        goto error;
68
0
    }
69
0
    icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR, ICAL_ERROR_NONFATAL);
70
0
    e = icalerrno;
71
0
    icalerror_set_errno(ICAL_NO_ERROR);
72
73
0
    tr.time = icaltime_from_string(str);
74
75
0
    if (icaltime_is_null_time(tr.time)) {
76
0
        tr.duration = icaldurationtype_from_string(str);
77
78
0
        if (icaldurationtype_is_bad_duration(tr.duration)) {
79
0
            goto error;
80
0
        }
81
0
    }
82
83
0
    icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR, es);
84
0
    icalerror_set_errno(e);
85
0
    return tr;
86
87
0
error:
88
0
    icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR, es);
89
0
    icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
90
0
    return tr;
91
0
}
92
93
struct icalreqstattype icalreqstattype_from_string(const char *str)
94
26.3k
{
95
26.3k
    const char *s, *p1, *p2;
96
26.3k
    struct icalreqstattype stat;
97
26.3k
    short major = 0, minor = 0;
98
99
26.3k
    icalerror_check_arg((str != 0), "str");
100
101
26.3k
    stat.code = ICAL_UNKNOWN_STATUS;
102
26.3k
    stat.debug = 0;
103
26.3k
    stat.desc = 0;
104
105
    // Don't allow (fuzzer) garbage chars anywhere in the reqstat string
106
26.3k
    s = str;
107
    /* cppcheck-suppress nullPointerRedundantCheck */
108
264k
    while (*s && isprint((unsigned char)*s)) {
109
238k
        ++s;
110
238k
    }
111
26.3k
    if (*s != '\0') {
112
        // garbage encountered. return the empty stat
113
723
        return stat;
114
723
    }
115
116
    /* Get the status numbers */
117
118
25.6k
    sscanf(str, "%hd.%hd", &major, &minor);
119
120
25.6k
    if (major <= 0 || minor < 0) {
121
997
        icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
122
997
        return stat;
123
997
    }
124
125
24.6k
    stat.code = icalenum_num_to_reqstat(major, minor);
126
127
24.6k
    if (stat.code == ICAL_UNKNOWN_STATUS) {
128
774
        icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
129
774
        return stat;
130
774
    }
131
132
23.8k
    p1 = strchr(str, ';');
133
134
23.8k
    if (p1 == 0) {
135
        /*    icalerror_set_errno(ICAL_BADARG_ERROR);*/
136
622
        return stat;
137
622
    }
138
139
    /* Just ignore the second clause; it will be taken from inside the library
140
     */
141
142
23.2k
    p2 = strchr(p1 + 1, ';');
143
23.2k
    if (p2 != 0 && *p2 != 0) {
144
22.4k
        stat.debug = icalmemory_tmp_copy(p2 + 1);
145
22.4k
    }
146
147
23.2k
    return stat;
148
23.8k
}
149
150
const char *icalreqstattype_as_string(struct icalreqstattype stat)
151
0
{
152
0
    char *buf;
153
154
0
    buf = icalreqstattype_as_string_r(stat);
155
0
    icalmemory_add_tmp_buffer(buf);
156
0
    return buf;
157
0
}
158
159
char *icalreqstattype_as_string_r(struct icalreqstattype stat)
160
6.05M
{
161
6.05M
    char *temp;
162
163
6.05M
    icalerror_check_arg_rz((stat.code != ICAL_UNKNOWN_STATUS), "Status");
164
165
6.05M
    temp = (char *)icalmemory_new_buffer(TMP_BUF_SIZE);
166
167
6.05M
    if (stat.desc == 0) {
168
6.05M
        stat.desc = icalenum_reqstat_desc(stat.code);
169
6.05M
    }
170
171
6.05M
    if (stat.debug != 0) {
172
749
        snprintf(temp, TMP_BUF_SIZE, "%d.%d;%s;%s", icalenum_reqstat_major(stat.code),
173
749
                 icalenum_reqstat_minor(stat.code), stat.desc, stat.debug);
174
175
6.05M
    } else {
176
6.05M
        snprintf(temp, TMP_BUF_SIZE, "%d.%d;%s", icalenum_reqstat_major(stat.code),
177
6.05M
                 icalenum_reqstat_minor(stat.code), stat.desc);
178
6.05M
    }
179
180
6.05M
    return temp;
181
6.05M
}
182
183
ical_unknown_token_handling ical_get_unknown_token_handling_setting(void)
184
83.8k
{
185
83.8k
    ical_unknown_token_handling myHandling;
186
187
83.8k
#if ICAL_SYNC_MODE == ICAL_SYNC_MODE_PTHREAD
188
83.8k
    pthread_mutex_lock(&unk_token_mutex);
189
83.8k
#endif
190
191
83.8k
    myHandling = unknownTokenHandling;
192
193
83.8k
#if ICAL_SYNC_MODE == ICAL_SYNC_MODE_PTHREAD
194
83.8k
    pthread_mutex_unlock(&unk_token_mutex);
195
83.8k
#endif
196
197
83.8k
    return myHandling;
198
83.8k
}
199
200
void ical_set_unknown_token_handling_setting(ical_unknown_token_handling newSetting)
201
0
{
202
0
#if ICAL_SYNC_MODE == ICAL_SYNC_MODE_PTHREAD
203
0
    pthread_mutex_lock(&unk_token_mutex);
204
0
#endif
205
206
0
    unknownTokenHandling = newSetting;
207
208
0
#if ICAL_SYNC_MODE == ICAL_SYNC_MODE_PTHREAD
209
0
    pthread_mutex_unlock(&unk_token_mutex);
210
0
#endif
211
0
}