1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-03-22 06:38:37 -05:00

do_text_internal: fix bug in the lpDx_maybe mechanism.

lpDx_maybe was a pointer defined to point at either lpDx itself or
NULL, depending on whether the code decided it needed to pass the lpDx
array of per-character pixel offsets to various functions during
drawing (based in turn on whether the font was variable-pitch).

lpDx is reallocated as necessary, which means lpDx_maybe must be kept
up to date. This was achieved by resetting it to lpDx if it was
already non-NULL.

But lpDx starts out as NULL before the first reallocation, so that
this can't work - it'll be initialised to NULL even if we _did_ want
to use it, and then at the first realloc, it won't be updated!

Before the previous commit turned lpDx from a static into an automatic
variable, this would have been a rare bug affecting only the first
call to the function. Now it will happen all the time, which is
better, because we can notice and fix it.

Replaced lpDx_maybe completely with a boolean flag indicating whether
we should pass lpDx to drawing functions.
This commit is contained in:
Simon Tatham 2023-05-27 15:26:38 +01:00
parent afb3dab1e9
commit 322984d635

View File

@ -3540,7 +3540,7 @@ static void do_text_internal(
bool is_cursor = false; bool is_cursor = false;
int *lpDx = NULL; int *lpDx = NULL;
size_t lpDx_len = 0; size_t lpDx_len = 0;
int *lpDx_maybe; bool use_lpDx;
wchar_t *wbuf = NULL; wchar_t *wbuf = NULL;
char *cbuf = NULL; char *cbuf = NULL;
size_t wbuflen = 0, cbuflen = 0; size_t wbuflen = 0, cbuflen = 0;
@ -3724,7 +3724,7 @@ static void do_text_internal(
*/ */
xoffset = char_width / 2; xoffset = char_width / 2;
SetTextAlign(wgs->wintw_hdc, TA_TOP | TA_CENTER | TA_NOUPDATECP); SetTextAlign(wgs->wintw_hdc, TA_TOP | TA_CENTER | TA_NOUPDATECP);
lpDx_maybe = NULL; use_lpDx = false;
maxlen = 1; maxlen = 1;
} else { } else {
/* /*
@ -3733,7 +3733,7 @@ static void do_text_internal(
*/ */
xoffset = 0; xoffset = 0;
SetTextAlign(wgs->wintw_hdc, TA_TOP | TA_LEFT | TA_NOUPDATECP); SetTextAlign(wgs->wintw_hdc, TA_TOP | TA_LEFT | TA_NOUPDATECP);
lpDx_maybe = lpDx; use_lpDx = true;
maxlen = len; maxlen = len;
} }
@ -3753,10 +3753,8 @@ static void do_text_internal(
len += 2; len += 2;
} }
if (len > lpDx_len) { if (len > lpDx_len)
sgrowarray(lpDx, lpDx_len, len); sgrowarray(lpDx, lpDx_len, len);
if (lpDx_maybe) lpDx_maybe = lpDx;
}
{ {
int i; int i;
@ -3816,13 +3814,14 @@ static void do_text_internal(
y - font_height * (lattr == LATTR_BOT) + text_adjust, y - font_height * (lattr == LATTR_BOT) + text_adjust,
ETO_CLIPPED | (opaque ? ETO_OPAQUE : 0), ETO_CLIPPED | (opaque ? ETO_OPAQUE : 0),
&line_box, uni_buf, nlen, &line_box, uni_buf, nlen,
lpDx_maybe); (use_lpDx ? lpDx : NULL));
if (wgs->bold_font_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) { if (wgs->bold_font_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) {
SetBkMode(wgs->wintw_hdc, TRANSPARENT); SetBkMode(wgs->wintw_hdc, TRANSPARENT);
ExtTextOutW(wgs->wintw_hdc, x + xoffset - 1, ExtTextOutW(wgs->wintw_hdc, x + xoffset - 1,
y - font_height * (lattr == y - font_height * (lattr ==
LATTR_BOT) + text_adjust, LATTR_BOT) + text_adjust,
ETO_CLIPPED, &line_box, uni_buf, nlen, lpDx_maybe); ETO_CLIPPED, &line_box, uni_buf, nlen,
(use_lpDx ? lpDx : NULL));
} }
lpDx[0] = -1; lpDx[0] = -1;
@ -3834,7 +3833,7 @@ static void do_text_internal(
ExtTextOut(wgs->wintw_hdc, x + xoffset, ExtTextOut(wgs->wintw_hdc, x + xoffset,
y - font_height * (lattr == LATTR_BOT) + text_adjust, y - font_height * (lattr == LATTR_BOT) + text_adjust,
ETO_CLIPPED | (opaque ? ETO_OPAQUE : 0), ETO_CLIPPED | (opaque ? ETO_OPAQUE : 0),
&line_box, directbuf, len, lpDx_maybe); &line_box, directbuf, len, (use_lpDx ? lpDx : NULL));
if (wgs->bold_font_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) { if (wgs->bold_font_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) {
SetBkMode(wgs->wintw_hdc, TRANSPARENT); SetBkMode(wgs->wintw_hdc, TRANSPARENT);
@ -3850,7 +3849,8 @@ static void do_text_internal(
ExtTextOut(wgs->wintw_hdc, x + xoffset - 1, ExtTextOut(wgs->wintw_hdc, x + xoffset - 1,
y - font_height * (lattr == y - font_height * (lattr ==
LATTR_BOT) + text_adjust, LATTR_BOT) + text_adjust,
ETO_CLIPPED, &line_box, directbuf, len, lpDx_maybe); ETO_CLIPPED, &line_box, directbuf, len,
(use_lpDx ? lpDx : NULL));
} }
} else { } else {
/* And 'normal' unicode characters */ /* And 'normal' unicode characters */
@ -3870,7 +3870,8 @@ static void do_text_internal(
ExtTextOutW(wgs->wintw_hdc, x + xoffset - 1, ExtTextOutW(wgs->wintw_hdc, x + xoffset - 1,
y - font_height * (lattr == y - font_height * (lattr ==
LATTR_BOT) + text_adjust, LATTR_BOT) + text_adjust,
ETO_CLIPPED, &line_box, wbuf, len, lpDx_maybe); ETO_CLIPPED, &line_box, wbuf, len,
(use_lpDx ? lpDx : NULL));
} }
} }