diff options
Diffstat (limited to 'src/libical/icalparser.c')
-rw-r--r-- | src/libical/icalparser.c | 100 |
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); |