diff options
author | Kent Sutherland <git@ksuther.com> | 2014-06-02 19:50:15 -0700 |
---|---|---|
committer | Kent Sutherland <git@ksuther.com> | 2014-06-02 19:52:48 -0700 |
commit | de2836bc0bc6ac0494741a84ff2c76b537095556 (patch) | |
tree | 9d7344ed0ad02c24fa59b4611bca567babc795ce /src | |
parent | ab162d7b630dda956507551b862b3c45682d828c (diff) | |
download | libical-git-de2836bc0bc6ac0494741a84ff2c76b537095556.tar.gz |
Better handling of invalid TZIDs that look like GMT+05:00
This will fix problems with parsing parameters that come after a TZID parameter
Diffstat (limited to 'src')
-rw-r--r-- | src/libical/icalparser.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/src/libical/icalparser.c b/src/libical/icalparser.c index ef33617f..c5088fcc 100644 --- a/src/libical/icalparser.c +++ b/src/libical/icalparser.c @@ -919,18 +919,22 @@ icalcomponent* icalparser_add_line(icalparser* parser, icalparameter_set_xname(param,name); icalparameter_set_xvalue(param,pvalue); } - } else if (kind == ICAL_TZID_PARAMETER){ + } else if (kind == ICAL_TZID_PARAMETER && *(end - 1) != ';'){ /* - Special case handling for TZID to workaround invalid incoming data. + Special case handling for TZID to work around invalid incoming data. For example, Google Calendar will send back stuff like this: DTSTART;TZID=GMT+05:30:20120904T020000 - In this case we read to the last colon rather than the first colon. + In this case we read to the next semicolon or the last colon rather than the first colon. This way the TZID will become GMT+05:30 rather than trying to parse the date-time as 30:20120904T020000. + + This also handles properties that look like this: + DTSTART;TZID=GMT+05:30;VALUE=DATE-TIME:20120904T020000 */ char *lastColon = 0; char *nextColon = end; + char *nextSemicolon = parser_get_next_char(';', end, 1); /* Find the last colon in the line */ do { @@ -940,14 +944,24 @@ icalcomponent* icalparser_add_line(icalparser* parser, lastColon = nextColon; } } while (nextColon); + + if (lastColon && nextSemicolon && nextSemicolon < lastColon) { + /* + Ensures that we don't read past a semicolon + + Handles the following line: + DTSTART;TZID=GMT+05:30;VALUE=DATE-TIME:20120904T020000 + */ + lastColon = nextSemicolon; + } /* - Rebuild str so that it includes everything up to the last colon. + Rebuild str so that it includes everything up to the next semicolon or the last colon. So given the above example, str will go from "TZID=GMT+05" to "TZID=GMT+05:30" */ if (lastColon && *(lastColon + 1) != 0) { - char *strStart = line + sizeof(str); + char *strStart = line + strlen(name) + 2; end = lastColon + 1; |