From c3bbb22f131ea6e273d4921bd60c73e78a13e00b Mon Sep 17 00:00:00 2001 From: "Ying-Chun Liu (PaulLiu)" Date: Sat, 8 Aug 2020 03:45:19 +0800 Subject: [PATCH] src/codeconv.c: Fix CVE-2015-8614 This code comes from the latest claws-mail upstream which fixes the security issue. Signed-off-by: Ying-Chun Liu (PaulLiu) --- src/codeconv.c | 74 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 26 deletions(-) diff --git a/src/codeconv.c b/src/codeconv.c index 254843e..0efbc13 100644 --- a/src/codeconv.c +++ b/src/codeconv.c @@ -128,10 +128,14 @@ typedef enum void conv_jistoeuc(gchar *outbuf, gint outlen, const gchar *inbuf) { const guchar *in = inbuf; - guchar *out = outbuf; + gchar *out = outbuf; JISState state = JIS_ASCII; - while (*in != '\0') { + /* + * Loop outputs up to 3 bytes in each pass (aux kanji) and we + * need 1 byte to terminate the output + */ + while (*in != '\0' && (out - outbuf) < outlen - 4) { if (*in == ESC) { in++; if (*in == '$') { @@ -192,6 +196,7 @@ void conv_jistoeuc(gchar *outbuf, gint outlen, const gchar *inbuf) } *out = '\0'; + return ; } #define JIS_HWDAKUTEN 0x5e @@ -263,10 +268,15 @@ static gint conv_jis_hantozen(guchar *outbuf, guchar jis_code, guchar sound_sym) void conv_euctojis(gchar *outbuf, gint outlen, const gchar *inbuf) { const guchar *in = inbuf; - guchar *out = outbuf; + gchar *out = outbuf; JISState state = JIS_ASCII; - while (*in != '\0') { + /* + * Loop outputs up to 6 bytes in each pass (aux shift + aux + * kanji) and we need up to 4 bytes to terminate the output + * (ASCII shift + null) + */ + while (*in != '\0' && (out - outbuf) < outlen - 10) { if (isascii(*in)) { K_OUT(); *out++ = *in++; @@ -286,26 +296,32 @@ void conv_euctojis(gchar *outbuf, gint outlen, const gchar *inbuf) } } else if (iseuchwkana1(*in)) { if (iseuchwkana2(*(in + 1))) { - guchar jis_ch[2]; - gint len; - - if (iseuchwkana1(*(in + 2)) && - iseuchwkana2(*(in + 3))) - len = conv_jis_hantozen - (jis_ch, - *(in + 1), *(in + 3)); - else - len = conv_jis_hantozen - (jis_ch, - *(in + 1), '\0'); - if (len == 0) - in += 2; - else { - K_IN(); - in += len * 2; - *out++ = jis_ch[0]; - *out++ = jis_ch[1]; - } + if (0) { + HW_IN(); + in++; + *out++ = *in++ & 0x7f; + } else { + guchar jis_ch[2]; + gint len; + + if (iseuchwkana1(*(in + 2)) && + iseuchwkana2(*(in + 3))) + len = conv_jis_hantozen + (jis_ch, + *(in + 1), *(in + 3)); + else + len = conv_jis_hantozen + (jis_ch, + *(in + 1), '\0'); + if (len == 0) + in += 2; + else { + K_IN(); + in += len * 2; + *out++ = jis_ch[0]; + *out++ = jis_ch[1]; + } + } } else { K_OUT(); in++; @@ -340,14 +356,19 @@ void conv_euctojis(gchar *outbuf, gint outlen, const gchar *inbuf) K_OUT(); *out = '\0'; + return ; } void conv_sjistoeuc(gchar *outbuf, gint outlen, const gchar *inbuf) { const guchar *in = inbuf; - guchar *out = outbuf; + gchar *out = outbuf; - while (*in != '\0') { + /* + * Loop outputs up to 2 bytes in each pass and we need 1 byte + * to terminate the output + */ + while (*in != '\0' && (out - outbuf) < outlen - 3) { if (isascii(*in)) { *out++ = *in++; } else if (issjiskanji1(*in)) { @@ -386,6 +407,7 @@ void conv_sjistoeuc(gchar *outbuf, gint outlen, const gchar *inbuf) } *out = '\0'; + return ; } void conv_anytoeuc(gchar *outbuf, gint outlen, const gchar *inbuf)