From ffbf714c9e6665c13d9ce5d5a2feac812377a7c0 Mon Sep 17 00:00:00 2001
From: Lars Henriksen <LarsHenriksen@get2net.dk>
Date: Wed, 18 Mar 2020 23:36:14 +0100
Subject: Fix decoding of escaped characters in imported text

Stick strictly to RFC 5545, 3.3.11, Text, for SUMMARY and DESCRIPTION.
Adresses Github issue #271.

Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
---
 src/ical.c              | 31 ++++++++++++++++++++-----------
 test/data/ical-002.ical |  4 ++--
 test/data/ical-006.ical |  2 +-
 3 files changed, 23 insertions(+), 14 deletions(-)

diff --git a/src/ical.c b/src/ical.c
index bc3148e..f6b9bd9 100644
--- a/src/ical.c
+++ b/src/ical.c
@@ -440,8 +440,9 @@ ical_store_apoint(char *mesg, char *note, long start, long dur,
 }
 
 /*
- * Returns an allocated string representing the string given in argument once
- * unformatted.
+ * Returns an allocated string representing the argument string with escaped
+ * characters decoded, or NULL on error.
+ * The string is assumed to be the value part of a SUMMARY or DESCRIPTION line.
  */
 static char *ical_unformat_line(char *line)
 {
@@ -453,25 +454,29 @@ static char *ical_unformat_line(char *line)
 		switch (*p) {
 		case '\\':
 			switch (*(p + 1)) {
+			case 'N':
 			case 'n':
 				string_catf(&s, "%c", '\n');
 				p++;
 				break;
-			case 't':
-				string_catf(&s, "%c", '\t');
-				p++;
-				break;
+			case '\\':
 			case ';':
-			case ':':
 			case ',':
 				string_catf(&s, "%c", *(p + 1));
 				p++;
 				break;
 			default:
-				string_catf(&s, "%c", *p);
-				break;
+				mem_free(s.buf);
+				return NULL;
 			}
 			break;
+		case ',':
+		case ';':
+			/*
+			 * No list or field separator allowed.
+			 */
+			mem_free(s.buf);
+			return NULL;
 		default:
 			string_catf(&s, "%c", *p);
 			break;
@@ -928,8 +933,12 @@ static char *ical_read_summary(char *line, unsigned *noskipped,
 	}
 
 	/* Event summaries must not contain newlines. */
-	for (p = strchr(summary, '\n'); p; p = strchr(p, '\n'))
-		*p = ' ';
+	if (strchr(summary, '\n')) {
+		ical_log(log, item_type, itemline, _("line break in summary."));
+		(*noskipped)++;
+		mem_free(summary);
+		return NULL;
+	}
 
 	return summary;
 }
diff --git a/test/data/ical-002.ical b/test/data/ical-002.ical
index 915b84e..b9f6538 100644
--- a/test/data/ical-002.ical
+++ b/test/data/ical-002.ical
@@ -8,12 +8,12 @@ END:VEVENT
 BEGIN:VEVENT
 DTSTART:20000101T000000
 DURATION:P1DT1H1M1S
-SUMMARY:One day, one hour, one minute and one second
+SUMMARY:One day\, one hour\, one minute and one second
 END:VEVENT
 BEGIN:VEVENT
 DTSTART:20000101T000000
 DURATION:PT1H1M1S
-SUMMARY:One hour, one minute and one second
+SUMMARY:One hour\, one minute and one second
 END:VEVENT
 BEGIN:VEVENT
 DTSTART:20000101T000000
diff --git a/test/data/ical-006.ical b/test/data/ical-006.ical
index 374ac2d..96c0b2c 100644
--- a/test/data/ical-006.ical
+++ b/test/data/ical-006.ical
@@ -56,7 +56,7 @@ DTSTART:20120601T150000
 DURATION:PT5H10S
 END:VEVENT
 BEGIN:VEVENT
-SUMMARY:5 hours, 30 minutes and 10 seconds
+SUMMARY:5 hours\, 30 minutes and 10 seconds
 DTSTART:20120601T150000
 DURATION:PT5H30M10S
 END:VEVENT
-- 
cgit v1.2.3-70-g09d2