From 5d937a51725609adcfba2c663ca4c1fe65974a55 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt 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(-) Index: libical-3.0.17/src/libicalvcal/vcc.c =================================================================== --- libical-3.0.17.orig/src/libicalvcal/vcc.c +++ libical-3.0.17/src/libicalvcal/vcc.c @@ -1005,31 +1005,25 @@ static char* lexGetQuotedPrintable(void) 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': { Index: libical-3.0.17/src/libicalvcal/vcc.y =================================================================== --- libical-3.0.17.orig/src/libicalvcal/vcc.y +++ libical-3.0.17/src/libicalvcal/vcc.y @@ -969,31 +969,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': {