Hello community, here is the log from the commit of package libical for openSUSE:Factory checked in at 2018-11-18 23:23:40 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libical (Old) and /work/SRC/openSUSE:Factory/.libical.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libical" Sun Nov 18 23:23:40 2018 rev:42 rq:648853 version:3.0.4 Changes: -------- --- /work/SRC/openSUSE:Factory/libical/libical.changes 2018-09-26 16:00:53.548548950 +0200 +++ /work/SRC/openSUSE:Factory/.libical.new/libical.changes 2018-11-18 23:23:53.882083807 +0100 @@ -1,0 +2,11 @@ +Fri Nov 9 00:52:39 UTC 2018 - Jan Engelhardt <[email protected]> + +- Add patches 0001-vcc.y-factor-out-hexdigit-conversion.patch, + 0002-vcc.y-fix-infinite-loop-with-lower-case-hex-digits.patch, + 0003-vcc.y-fix-infinite-loop-with-non-hex-digits.patch, + 0004-vobject.c-vCard-Unicode-reading-support.patch, + 0005-vcc.y-do-not-ignore-field-separator-in-QUOTED-PRINTA.patch + to support Unicode in VCF (and fix infinite loops). + [https://github.com/libical/libical/pull/354 ] + +------------------------------------------------------------------- New: ---- 0001-vcc.y-factor-out-hexdigit-conversion.patch 0002-vcc.y-fix-infinite-loop-with-lower-case-hex-digits.patch 0003-vcc.y-fix-infinite-loop-with-non-hex-digits.patch 0004-vobject.c-vCard-Unicode-reading-support.patch 0005-vcc.y-do-not-ignore-field-separator-in-QUOTED-PRINTA.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libical.spec ++++++ --- /var/tmp/diff_new_pack.NJolM7/_old 2018-11-18 23:23:55.126082290 +0100 +++ /var/tmp/diff_new_pack.NJolM7/_new 2018-11-18 23:23:55.126082290 +0100 @@ -12,7 +12,7 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # @@ -27,6 +27,11 @@ #Git-Clone: https://github.com/libical/libical Source: https://github.com/libical/libical/releases/download/v%{version}/%{name}-%{version}.tar.gz Source2: baselibs.conf +Patch1: 0001-vcc.y-factor-out-hexdigit-conversion.patch +Patch2: 0002-vcc.y-fix-infinite-loop-with-lower-case-hex-digits.patch +Patch3: 0003-vcc.y-fix-infinite-loop-with-non-hex-digits.patch +Patch4: 0004-vobject.c-vCard-Unicode-reading-support.patch +Patch5: 0005-vcc.y-do-not-ignore-field-separator-in-QUOTED-PRINTA.patch BuildRequires: cmake >= 3.1 BuildRequires: gcc-c++ BuildRequires: pkgconfig @@ -75,7 +80,7 @@ component properties, parameters, and subcomponents. %prep -%setup -q +%autosetup -p1 %build %cmake -DICAL_GLIB=false -DSHARED_ONLY=true ++++++ 0001-vcc.y-factor-out-hexdigit-conversion.patch ++++++ >From 6c167138a204cd2e0580036bad32a51dae05c80b Mon Sep 17 00:00:00 2001 From: Jan Engelhardt <[email protected]> Date: Mon, 17 Sep 2018 16:47:16 +0200 Subject: [PATCH 1/5] vcc.y - factor out hexdigit conversion References: https://github.com/libical/libical/pull/354 --- src/libicalvcal/vcc.c | 17 +++++++++++------ src/libicalvcal/vcc.y | 17 +++++++++++------ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/libicalvcal/vcc.c b/src/libicalvcal/vcc.c index d47bc099..c2a743c2 100644 --- a/src/libicalvcal/vcc.c +++ b/src/libicalvcal/vcc.c @@ -1126,6 +1126,15 @@ static int match_begin_end_name(int end) { return 0; } +static int hexdigit_decode(char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + static char* lexGetQuotedPrintable() { char cur; @@ -1139,12 +1148,8 @@ static char* lexGetQuotedPrintable() int next[2]; int i; for (i = 0; i < 2; i++) { - next[i] = lexGetc(); - if (next[i] >= '0' && next[i] <= '9') - c = c * 16 + next[i] - '0'; - else if (next[i] >= 'A' && next[i] <= 'F') - c = c * 16 + next[i] - 'A' + 10; - else + next[i] = hexdigit_decode(lexGetc()); + if (next[i] < 0) break; } if (i == 0) { diff --git a/src/libicalvcal/vcc.y b/src/libicalvcal/vcc.y index d97ea83b..45243df6 100644 --- a/src/libicalvcal/vcc.y +++ b/src/libicalvcal/vcc.y @@ -947,6 +947,15 @@ static int match_begin_end_name(int end) { return 0; } +static int hexdigit_decode(char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + static char* lexGetQuotedPrintable() { char cur; @@ -960,12 +969,8 @@ static char* lexGetQuotedPrintable() int next[2]; int i; for (i = 0; i < 2; i++) { - next[i] = lexGetc(); - if (next[i] >= '0' && next[i] <= '9') - c = c * 16 + next[i] - '0'; - else if (next[i] >= 'A' && next[i] <= 'F') - c = c * 16 + next[i] - 'A' + 10; - else + next[i] = hexdigit_decode(lexGetc()); + if (next[i] < 0) break; } if (i == 0) { -- 2.19.1 ++++++ 0002-vcc.y-fix-infinite-loop-with-lower-case-hex-digits.patch ++++++ >From bf83a0d664f46229836852f5b41539c263c3b921 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt <[email protected]> Date: Mon, 17 Sep 2018 16:36:36 +0200 Subject: [PATCH 2/5] vcc.y - fix infinite loop with lower-case hex digits References: https://github.com/libical/libical/pull/354 When lower-case hex digits are used in a quoted-printable-encoded character, an infinite loop would occur in the vcard parser. "N;ENCODING=QUOTED-PRINTABLE:=c3=a4=c3=b6;=c3=bC=c3=9f\n" References: #353 --- src/libicalvcal/vcc.c | 2 ++ src/libicalvcal/vcc.y | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/libicalvcal/vcc.c b/src/libicalvcal/vcc.c index c2a743c2..29354df4 100644 --- a/src/libicalvcal/vcc.c +++ b/src/libicalvcal/vcc.c @@ -1132,6 +1132,8 @@ static int hexdigit_decode(char c) return c - '0'; if (c >= 'A' && c <= 'F') return c - 'A' + 10; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; return -1; } diff --git a/src/libicalvcal/vcc.y b/src/libicalvcal/vcc.y index 45243df6..a052e9a2 100644 --- a/src/libicalvcal/vcc.y +++ b/src/libicalvcal/vcc.y @@ -953,6 +953,8 @@ static int hexdigit_decode(char c) return c - '0'; if (c >= 'A' && c <= 'F') return c - 'A' + 10; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; return -1; } -- 2.19.1 ++++++ 0003-vcc.y-fix-infinite-loop-with-non-hex-digits.patch ++++++ >From 5d937a51725609adcfba2c663ca4c1fe65974a55 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt <[email protected]> Date: Mon, 17 Sep 2018 17:15:28 +0200 Subject: [PATCH 3/5] vcc.y - fix infinite loop with non-hex digits References: https://github.com/libical/libical/pull/354 When nonsensical characters are used in a QP character, an infinite loop would occur in the vcard parser. "N;ENCODING=QUOTED-PRINTABLE:=c3=g4\n" References: #353 --- src/libicalvcal/vcc.c | 38 ++++++++++++++++---------------------- src/libicalvcal/vcc.y | 38 ++++++++++++++++---------------------- 2 files changed, 32 insertions(+), 44 deletions(-) diff --git a/src/libicalvcal/vcc.c b/src/libicalvcal/vcc.c index 29354df4..f723a4e1 100644 --- a/src/libicalvcal/vcc.c +++ b/src/libicalvcal/vcc.c @@ -1146,31 +1146,25 @@ static char* lexGetQuotedPrintable() cur = lexGetc(); switch (cur) { case '=': { - int c = 0; - int next[2]; - int i; - for (i = 0; i < 2; i++) { - next[i] = hexdigit_decode(lexGetc()); - if (next[i] < 0) - break; + int c = 0, d; + cur = lexGetc(); + if (cur == '\n') { + ++mime_lineNum; + break; } - if (i == 0) { - /* single '=' follow by LINESEP is continuation sign? */ - if (next[0] == '\n') { - ++mime_lineNum; - } - else { - lexPushLookaheadc('='); - goto EndString; - } + d = hexdigit_decode(cur); + if (d < 0) { + lexAppendc(cur); + break; } - else if (i == 1) { - lexPushLookaheadc(next[1]); - lexPushLookaheadc(next[0]); - lexAppendc('='); - } else { - lexAppendc(c); + c = d << 4; + cur = lexGetc(); + d = hexdigit_decode(cur); + if (d < 0) { + lexAppendc(cur); + break; } + lexAppendc(c | d); break; } /* '=' */ case '\n': { diff --git a/src/libicalvcal/vcc.y b/src/libicalvcal/vcc.y index a052e9a2..4f52fe35 100644 --- a/src/libicalvcal/vcc.y +++ b/src/libicalvcal/vcc.y @@ -967,31 +967,25 @@ static char* lexGetQuotedPrintable() cur = lexGetc(); switch (cur) { case '=': { - int c = 0; - int next[2]; - int i; - for (i = 0; i < 2; i++) { - next[i] = hexdigit_decode(lexGetc()); - if (next[i] < 0) - break; + int c = 0, d; + cur = lexGetc(); + if (cur == '\n') { + ++mime_lineNum; + break; } - if (i == 0) { - /* single '=' follow by LINESEP is continuation sign? */ - if (next[0] == '\n') { - ++mime_lineNum; - } - else { - lexPushLookaheadc('='); - goto EndString; - } + d = hexdigit_decode(cur); + if (d < 0) { + lexAppendc(cur); + break; } - else if (i == 1) { - lexPushLookaheadc(next[1]); - lexPushLookaheadc(next[0]); - lexAppendc('='); - } else { - lexAppendc(c); + c = d << 4; + cur = lexGetc(); + d = hexdigit_decode(cur); + if (d < 0) { + lexAppendc(cur); + break; } + lexAppendc(c | d); break; } /* '=' */ case '\n': { -- 2.19.1 ++++++ 0004-vobject.c-vCard-Unicode-reading-support.patch ++++++ >From aacb3875a9a645880cbfe014fb0c4cb078ff4342 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt <[email protected]> Date: Mon, 17 Sep 2018 21:27:43 +0200 Subject: [PATCH 4/5] vobject.c - vCard Unicode reading support References: https://github.com/libical/libical/pull/354 RFC 6350 declares vCard to be UTF-8 throughout without exceptions. However, any non-ASCII vCard content is garbled because the "fakeUnicode" botched the conversion to wchar_t: The conversion just copies values from char to wchar_t, which is neither correct for UTF-8 nor (a hypothetical) ISO-8859-1/-15 coded input. This patch fixes that. References: #353 --- src/libicalvcal/vobject.c | 94 ++++++++++++++++++++++++++++++++------- 1 file changed, 78 insertions(+), 16 deletions(-) diff --git a/src/libicalvcal/vobject.c b/src/libicalvcal/vobject.c index 10d0cf5a..b880716f 100644 --- a/src/libicalvcal/vobject.c +++ b/src/libicalvcal/vobject.c @@ -45,6 +45,9 @@ DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. #ifdef HAVE_CONFIG_H #include <config.h> #endif +#include <errno.h> +#include <iconv.h> +#include <stdint.h> #include "vobject.h" @@ -1414,27 +1417,86 @@ char* writeMemVObjects(char *s, int *len, VObject *list) /*---------------------------------------------------------------------- APIs to do fake Unicode stuff. ----------------------------------------------------------------------*/ +/* + * Convert UTF-8 to wide chars. + * + * The only place where this spells Unicode is 1.) in "UTF-8", 2.) when it does + * the secondary pass to replace \n and \r with U+2028 and 2029, respectively. + * That step blindly pretends wchar_t shares the Unicode codepoints (happens to + * work for the important contemporary platforms, but otherwise is nonsense). + */ wchar_t* fakeUnicode(const char *ps, size_t *bytes) { - wchar_t *r, *pw; - size_t len = strlen(ps)+1; + /* + * Assuming the input were all ASCII, then + * + * method1_out_size = zs * sizeof(wchar_t) + * + * would make sense. But if the input were all 3-byte UTF-8 codepoints, + * then that would be a large wasteful allocation, and + * + * method2_out_size = zs * sizeof(wchar_t) / 3 + * + * would be more reasonable. Since there is no way of knowing in + * advance what is in @ps, method 1 will be chosen if that is a 1KB + * allocation (or less), and method 2 otherwise. From there, the + * standard exponential progression for realloc is applied. + */ + size_t zs = strlen(ps), out_size, out_rem; + char *out_block, *out_iter; + iconv_t conv = iconv_open("wchar_t", "utf-8"); - pw = r = (wchar_t*)malloc(sizeof(wchar_t)*len); - if (bytes) - *bytes = len * sizeof(wchar_t); + if (conv == (iconv_t)-1) + return NULL; + if (zs >= (SIZE_MAX - sizeof(wchar_t)) / sizeof(wchar_t)) + /* Input is larger than anything we want to handle */ + return NULL; + /* Initial allocation size as per above. */ + out_size = out_rem = zs * sizeof(wchar_t); + if (out_size >= 1024 - sizeof(wchar_t)) + out_size /= 3; + out_iter = out_block = malloc(out_size + sizeof(wchar_t)); + if (out_block == NULL) { + iconv_close(conv); + return NULL; + } - while (*ps) { - if (*ps == '\n') - *pw = (wchar_t)0x2028; - else if (*ps == '\r') - *pw = (wchar_t)0x2029; - else - *pw = (wchar_t)(unsigned char)*ps; - ps++; pw++; - } - *pw = (wchar_t)0; + while (zs > 0) { + int ret; + errno = 0; + ret = iconv(conv, (char **)&ps, &zs, &out_iter, &out_rem); + if (ret >= 0) + continue; + if (errno == EILSEQ || errno == EINVAL) { + ++ps; + --zs; + continue; + } + if (errno != E2BIG) + break; + out_rem += out_size; + out_size *= 2; + char *new_block = realloc(out_block, out_size + sizeof(wchar_t)); + if (new_block == NULL) { + free(out_block); + iconv_close(conv); + return NULL; + } + out_iter = new_block + (out_iter - out_block); + out_block = new_block; + } - return r; + wchar_t *wide = (wchar_t *)out_block, *p = wide; + for (; p < (wchar_t *)(out_block + out_size - out_rem); ++p) { + if (*p == '\n') + *p = 0x2028; + else if (*p == '\r') + *p = 0x2029; + } + *p = L'\0'; + if (bytes != NULL) + *bytes = (char *)p - out_block; + return wide; } int uStrLen(const wchar_t *u) -- 2.19.1 ++++++ 0005-vcc.y-do-not-ignore-field-separator-in-QUOTED-PRINTA.patch ++++++ >From 5fbba6b0db3e13bb42a6208c408497469e501a26 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt <[email protected]> Date: Mon, 17 Sep 2018 22:05:03 +0200 Subject: [PATCH 5/5] vcc.y - do not ignore field separator in QUOTED-PRINTABLE mode References: https://github.com/libical/libical/pull/354 "N;ENCODING=QUOTED-PRINTABLE:=C3=A4=C3=B6;=C3=BC=C3=9F\n" was parsed as a single field, while in fact, it is two. References: #353 --- src/libicalvcal/vcc.c | 5 +++-- src/libicalvcal/vcc.y | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libicalvcal/vcc.c b/src/libicalvcal/vcc.c index f723a4e1..fd056992 100644 --- a/src/libicalvcal/vcc.c +++ b/src/libicalvcal/vcc.c @@ -1167,8 +1167,9 @@ static char* lexGetQuotedPrintable() lexAppendc(c | d); break; } /* '=' */ - case '\n': { - lexPushLookaheadc('\n'); + case '\n': + case ';': { + lexPushLookaheadc(cur); goto EndString; } case (char)EOF: diff --git a/src/libicalvcal/vcc.y b/src/libicalvcal/vcc.y index 4f52fe35..df770df6 100644 --- a/src/libicalvcal/vcc.y +++ b/src/libicalvcal/vcc.y @@ -988,8 +988,9 @@ static char* lexGetQuotedPrintable() lexAppendc(c | d); break; } /* '=' */ - case '\n': { - lexPushLookaheadc('\n'); + case '\n': + case ';': { + lexPushLookaheadc(cur); goto EndString; } case (char)EOF: -- 2.19.1
