From 92e447043fd89a272270b95500521df2de9f1588 Mon Sep 17 00:00:00 2001 From: Edward Whiting Date: Tue, 18 Aug 2020 13:17:24 +1000 Subject: [PATCH] Increase the resilience of CalendarParserImpl to superfluous newline characters between objects in the input file. --- .../ical4j/data/CalendarParserImpl.java | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/main/java/net/fortuna/ical4j/data/CalendarParserImpl.java b/src/main/java/net/fortuna/ical4j/data/CalendarParserImpl.java index d4f2499ff..4459a1a3a 100644 --- a/src/main/java/net/fortuna/ical4j/data/CalendarParserImpl.java +++ b/src/main/java/net/fortuna/ical4j/data/CalendarParserImpl.java @@ -112,6 +112,8 @@ private void parseCalendar(final StreamTokenizer tokeniser, Reader in, handler.startCalendar(); + absorbWhitespace(tokeniser, in); + // parse calendar properties.. propertyListParser.parse(tokeniser, in, handler); @@ -180,7 +182,8 @@ private void parseCalendarList(final StreamTokenizer tokeniser, Reader in, int ntok = assertToken(tokeniser, in, Calendar.BEGIN, false, true); while (ntok != StreamTokenizer.TT_EOF) { parseCalendar(tokeniser, in, handler); - ntok = absorbWhitespace(tokeniser, in, true); + absorbWhitespace(tokeniser, in); + ntok = nextToken(tokeniser, in, true); } } @@ -214,7 +217,8 @@ public void parse(final StreamTokenizer tokeniser, Reader in, } else if (!CompatibilityHints.isHintEnabled(CompatibilityHints.KEY_RELAXED_PARSING)) { throw new ParserException("Invalid property name", getLineNumber(tokeniser, in)); } - absorbWhitespace(tokeniser, in, false); + absorbWhitespace(tokeniser, in); + nextToken(tokeniser, in, false); // assertToken(tokeniser, StreamTokenizer.TT_WORD); } } @@ -394,7 +398,8 @@ private void parse(final StreamTokenizer tokeniser, Reader in, while (Component.BEGIN.equals(tokeniser.sval)) { componentParser.parse(tokeniser, in, handler); - absorbWhitespace(tokeniser, in, false); + absorbWhitespace(tokeniser, in); + nextToken(tokeniser, in, false); // assertToken(tokeniser, StreamTokenizer.TT_WORD); } } @@ -425,6 +430,7 @@ private void parse(final StreamTokenizer tokeniser, Reader in, handler.startComponent(name); assertToken(tokeniser, in, StreamTokenizer.TT_EOL); + absorbWhitespace(tokeniser, in); propertyListParser.parse(tokeniser, in, handler); @@ -579,10 +585,8 @@ private String getSvalIgnoringBom(StreamTokenizer tokeniser, Reader in, String t * @return int value of the ttype field of the tokeniser * @throws IOException */ - private int absorbWhitespace(final StreamTokenizer tokeniser, Reader in, boolean ignoreEOF) throws IOException, ParserException { - // HACK: absorb extraneous whitespace between components (KOrganizer).. - int ntok; - while ((ntok = nextToken(tokeniser, in, ignoreEOF)) == StreamTokenizer.TT_EOL) { + private void absorbWhitespace(final StreamTokenizer tokeniser, Reader in) throws IOException, ParserException { + while (nextToken(tokeniser, in, true) == StreamTokenizer.TT_EOL) { if (log.isTraceEnabled()) { log.trace("Absorbing extra whitespace.."); } @@ -590,7 +594,10 @@ private int absorbWhitespace(final StreamTokenizer tokeniser, Reader in, boolean if (log.isTraceEnabled()) { log.trace("Aborting: absorbing extra whitespace complete"); } - return ntok; + /* In effect, we only want to absorb extra newlines after the current + * token, and not absorb the current token, even if it is a newline. + */ + tokeniser.pushBack(); } /**