From 11f504c440d13da6cc95dcfeaa788fa28cd361bf Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Tue, 2 Jul 2019 21:22:01 +0100 Subject: [PATCH] Tighten assertions in Windows wc_to_mb. This assertion was supposed to be checking for the buffer overrun fixed by the previous commit, but because it checks the buffer index just _after_ writing into the buffer, it would have permitted a one-byte overrun before failing the assertion. --- windows/winucs.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/windows/winucs.c b/windows/winucs.c index eeafc83e..f5fbffe6 100644 --- a/windows/winucs.c +++ b/windows/winucs.c @@ -1170,21 +1170,28 @@ int wc_to_mb(int codepage, int flags, const wchar_t *wcstr, int wclen, wchar_t ch = wcstr[i]; int by; char *p1; - if (ucsdata->uni_tbl && (p1 = ucsdata->uni_tbl[(ch >> 8) & 0xFF]) - && (by = p1[ch & 0xFF])) - *p++ = by; + + #define WRITECH(chr) do \ + { \ + assert(p - mbstr < mblen); \ + *p++ = (char)(chr); \ + } while (0) + + if (ucsdata->uni_tbl && + (p1 = ucsdata->uni_tbl[(ch >> 8) & 0xFF]) != NULL && + (by = p1[ch & 0xFF]) != '\0') + WRITECH(by); else if (ch < 0x80) - *p++ = (char) ch; - else if (defchr) { - int j; - for (j = 0; defchr[j]; j++) - *p++ = defchr[j]; - } + WRITECH(ch); + else if (defchr) + for (const char *q = defchr; *q; q++) + WRITECH(*q); #if 1 else - *p++ = '.'; + WRITECH('.'); #endif - assert(p - mbstr < mblen); + + #undef WRITECH } return p - mbstr; } else {