summaryrefslogtreecommitdiff
path: root/src/libical/icalparser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libical/icalparser.c')
-rw-r--r--src/libical/icalparser.c100
1 files changed, 52 insertions, 48 deletions
diff --git a/src/libical/icalparser.c b/src/libical/icalparser.c
index 72578840..5015d561 100644
--- a/src/libical/icalparser.c
+++ b/src/libical/icalparser.c
@@ -2,31 +2,11 @@
FILE: icalparser.c
CREATOR: eric 04 August 1999
- (C) COPYRIGHT 2000, Eric Busboom <eric@civicknowledge.com>
+ SPDX-FileCopyrightText: 2000, Eric Busboom <eric@civicknowledge.com>
- This library is free software; you can redistribute it and/or modify
- it under the terms of either:
+ SPDX-License-Identifier: LGPL-2.1-only OR MPL-2.0
- The LGPL as published by the Free Software Foundation, version
- 2.1, available at: https://www.gnu.org/licenses/lgpl-2.1.html
-
- Or:
-
- The Mozilla Public License Version 2.0. You may obtain a copy of
- the License at https://www.mozilla.org/MPL/
-
- This library is free software; you can redistribute it and/or modify
- it under the terms of either:
-
- The LGPL as published by the Free Software Foundation, version
- 2.1, available at: https://www.gnu.org/licenses/lgpl-2.1.html
-
- Or:
-
- The Mozilla Public License Version 2.0. You may obtain a copy of
- the License at https://www.mozilla.org/MPL/
-
- The Initial Developer of the Original Code is Eric Busboom
+ The Initial Developer of the Original Code is Eric Busboom
======================================================================*/
#ifdef HAVE_CONFIG_H
@@ -46,6 +26,7 @@
#define TMP_BUF_SIZE 80
#define MAXIMUM_ALLOWED_PARAMETERS 100
#define MAXIMUM_ALLOWED_MULTIPLE_VALUES 500
+#define MAXIMUM_ALLOWED_ERRORS 100 // Limit the number of errors created by insert_error
struct icalparser_impl
{
@@ -58,6 +39,7 @@ struct icalparser_impl
int version;
int level;
int lineno;
+ int error_count;
icalparser_state state;
pvl_list components;
@@ -100,7 +82,7 @@ icalparser *icalparser_new(void)
{
struct icalparser_impl *impl = 0;
- if ((impl = (struct icalparser_impl *)malloc(sizeof(struct icalparser_impl))) == 0) {
+ if ((impl = (struct icalparser_impl *)icalmemory_new_buffer(sizeof(struct icalparser_impl))) == 0) {
icalerror_set_errno(ICAL_NEWFAILED_ERROR);
return 0;
}
@@ -113,6 +95,7 @@ icalparser *icalparser_new(void)
impl->buffer_full = 0;
impl->continuation_line = 0;
impl->lineno = 0;
+ impl->error_count = 0;
memset(impl->temp, 0, TMP_BUF_SIZE);
return (icalparser *) impl;
@@ -132,7 +115,7 @@ void icalparser_free(icalparser *parser)
pvl_free(parser->components);
- free(parser);
+ icalmemory_free_buffer(parser);
}
void icalparser_set_gen_data(icalparser *parser, void *data)
@@ -219,20 +202,28 @@ static void parser_decode_param_value(char *value)
char *in, *out;
for (in = out = value; *in; in++, out++) {
- if (*in == '^' && strspn(in+1, "n^'")) {
- switch (*++in) {
+ int found_escaped_char = 0;
+
+ if (*in == '^') {
+ switch (*(in + 1)) {
case 'n':
*out = '\n';
+ found_escaped_char = 1;
break;
-
case '^':
*out = '^';
+ found_escaped_char = 1;
break;
case '\'':
*out = '"';
+ found_escaped_char = 1;
break;
}
+ }
+
+ if (found_escaped_char) {
+ ++in;
} else {
*out = *in;
}
@@ -312,7 +303,7 @@ static char *parser_get_param_name_heap(char *line, char **end)
*end = *end + 1;
next = (**end == '"') ? *end : parser_get_next_char('"', *end, 0);
if (next == 0) {
- free(str);
+ icalmemory_free_buffer(str);
*end = NULL;
return 0;
}
@@ -546,7 +537,7 @@ char *icalparser_get_line(icalparser *parser,
} else {
/* No data in output; return and signal that there
is no more input */
- free(line);
+ icalmemory_free_buffer(line);
return 0;
}
}
@@ -591,11 +582,15 @@ char *icalparser_get_line(icalparser *parser,
return line;
}
-static void insert_error(icalcomponent *comp, const char *text,
+static void insert_error(icalparser *parser, icalcomponent *comp, const char *text,
const char *message, icalparameter_xlicerrortype type)
{
char temp[1024];
+ if (parser->error_count > MAXIMUM_ALLOWED_ERRORS) {
+ return;
+ }
+
if (text == 0) {
snprintf(temp, 1024, "%s:", message);
} else {
@@ -605,6 +600,8 @@ static void insert_error(icalcomponent *comp, const char *text,
icalcomponent_add_property(
comp,
icalproperty_vanew_xlicerror(temp, icalparameter_new_xlicerrortype(type), (void *)0));
+
+ parser->error_count++;
}
static int line_is_blank(char *line)
@@ -644,8 +641,8 @@ icalcomponent *icalparser_parse(icalparser *parser,
/* This is bad news... assert? */
}
- assert(parser->root_component == 0);
- assert(pvl_count(parser->components) == 0);
+ icalassert(parser->root_component == 0);
+ icalassert(pvl_count(parser->components) == 0);
if (root == 0) {
/* Just one component */
@@ -665,7 +662,7 @@ icalcomponent *icalparser_parse(icalparser *parser,
} else {
/* Badness */
- assert(0);
+ icalassert(0);
}
c = 0;
@@ -718,7 +715,7 @@ icalcomponent *icalparser_add_line(icalparser *parser, char *line)
if (tail) {
insert_error(
- tail, line,
+ parser, tail, line,
"Got a data line, but could not find a property name or component begin tag",
ICAL_XLICERRORTYPE_COMPONENTPARSEERROR);
}
@@ -745,11 +742,15 @@ icalcomponent *icalparser_add_line(icalparser *parser, char *line)
comp_kind = icalenum_string_to_component_kind(str);
- c = icalcomponent_new(comp_kind);
+ if (comp_kind == ICAL_X_COMPONENT) {
+ c = icalcomponent_new_x(str);
+ } else {
+ c = icalcomponent_new(comp_kind);
+ }
if (c == 0) {
c = icalcomponent_new(ICAL_XLICINVALID_COMPONENT);
- insert_error(c, str, "Parse error in component name",
+ insert_error(parser, c, str, "Parse error in component name",
ICAL_XLICERRORTYPE_COMPONENTPARSEERROR);
}
@@ -799,7 +800,7 @@ icalcomponent *icalparser_add_line(icalparser *parser, char *line)
(void)icalparser_clean(parser); /* may reset parser->root_component */
}
- assert(pvl_count(parser->components) == 0);
+ icalassert(pvl_count(parser->components) == 0);
parser->state = ICALPARSER_SUCCESS;
rtrn = parser->root_component;
@@ -850,7 +851,7 @@ icalcomponent *icalparser_add_line(icalparser *parser, char *line)
} else {
icalcomponent *tail = pvl_data(pvl_tail(parser->components));
- insert_error(tail, str, "Parse error in property name",
+ insert_error(parser, tail, str, "Parse error in property name",
ICAL_XLICERRORTYPE_PROPERTYPARSEERROR);
tail = 0;
@@ -901,7 +902,7 @@ icalcomponent *icalparser_add_line(icalparser *parser, char *line)
if (name_heap == 0) {
/* 'tail' defined above */
- insert_error(tail, str, "Can't parse parameter name",
+ insert_error(parser, tail, str, "Can't parse parameter name",
ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR);
tail = 0;
break;
@@ -1012,7 +1013,7 @@ icalcomponent *icalparser_add_line(icalparser *parser, char *line)
/* Change for mozilla */
/* have the option of being flexible towards unsupported parameters */
#if ICAL_ERRORS_ARE_FATAL == 1
- insert_error(tail, str, "Can't parse parameter name",
+ insert_error(parser, tail, str, "Can't parse parameter name",
ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR);
tail = 0;
parser->state = ICALPARSER_ERROR;
@@ -1054,7 +1055,7 @@ icalcomponent *icalparser_add_line(icalparser *parser, char *line)
if (param == 0) {
/* 'tail' defined above */
- insert_error(tail, str, "Can't parse parameter value",
+ insert_error(parser, tail, str, "Can't parse parameter value",
ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR);
tail = 0;
@@ -1082,7 +1083,7 @@ icalcomponent *icalparser_add_line(icalparser *parser, char *line)
char *tmp_buf = icalmemory_tmp_buffer(tmp_buf_len);
snprintf(tmp_buf, tmp_buf_len, "%s %s", err_str, prop_str);
- insert_error(tail, str, tmp_buf,
+ insert_error(parser, tail, str, tmp_buf,
ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR);
value_kind = icalproperty_kind_to_value_kind(prop_kind);
@@ -1141,7 +1142,7 @@ icalcomponent *icalparser_add_line(icalparser *parser, char *line)
if (vcount > 0) {
/* Actually, only clone after the second value */
- icalproperty *clone = icalproperty_new_clone(prop);
+ icalproperty *clone = icalproperty_clone(prop);
icalcomponent *tail = pvl_data(pvl_tail(parser->components));
icalcomponent_add_property(tail, clone);
@@ -1163,7 +1164,7 @@ icalcomponent *icalparser_add_line(icalparser *parser, char *line)
icalvalue_kind_to_string(value_kind),
icalproperty_kind_to_string(prop_kind));
- insert_error(tail, str, temp, ICAL_XLICERRORTYPE_VALUEPARSEERROR);
+ insert_error(parser, tail, str, temp, ICAL_XLICERRORTYPE_VALUEPARSEERROR);
/* Remove the troublesome property */
icalcomponent_remove_property(tail, prop);
@@ -1202,7 +1203,7 @@ icalcomponent *icalparser_add_line(icalparser *parser, char *line)
snprintf(temp, sizeof(temp), "No value for %s property. Removing entire property",
icalproperty_kind_to_string(prop_kind));
- insert_error(tail, str, temp, ICAL_XLICERRORTYPE_VALUEPARSEERROR);
+ insert_error(parser, tail, str, temp, ICAL_XLICERRORTYPE_VALUEPARSEERROR);
/* Remove the troublesome property */
icalcomponent_remove_property(tail, prop);
@@ -1226,7 +1227,7 @@ icalcomponent *icalparser_add_line(icalparser *parser, char *line)
if (pvl_data(pvl_tail(parser->components)) == 0 && parser->level == 0) {
/* HACK. Does this clause ever get executed? */
parser->state = ICALPARSER_SUCCESS;
- assert(0);
+ icalassert(0);
return parser->root_component;
} else {
parser->state = ICALPARSER_IN_PROGRESS;
@@ -1250,7 +1251,7 @@ icalcomponent *icalparser_clean(icalparser *parser)
while ((tail = pvl_data(pvl_tail(parser->components))) != 0) {
- insert_error(tail, " ",
+ insert_error(parser, tail, " ",
"Missing END tag for this component. Closing component at end of input.",
ICAL_XLICERRORTYPE_COMPONENTPARSEERROR);
@@ -1344,6 +1345,9 @@ icalcomponent *icalparser_parse_string(const char *str)
d.str = str;
p = icalparser_new();
+ if (!p)
+ return NULL;
+
icalparser_set_gen_data(p, &d);
icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR, ICAL_ERROR_NONFATAL);