1From 787636674918873a091e7a4ef5977263ba982322 Mon Sep 17 00:00:00 2001 2From: "Thomas E. Dickey" <dickey@invisible-island.net> 3Date: Sun, 23 Oct 2022 22:59:52 +0000 4Subject: [PATCH] snapshot of project "xterm", label xterm-374c 5 6Upstream-Status: https://github.com/ThomasDickey/xterm-snapshots/commit/787636674918873a091e7a4ef5977263ba982322 7CVE: CVE-2022-45063 8 9Signed-off-by: Siddharth Doshi <sdoshi@mvista.com> 10--- 11 button.c | 14 +-- 12 charproc.c | 9 +- 13 doublechr.c | 4 +- 14 fontutils.c | 266 ++++++++++++++++++++++++++----------------------- 15 fontutils.h | 4 +- 16 misc.c | 7 +- 17 screen.c | 2 +- 18 xterm.h | 2 +- 19 xterm.log.html | 6 ++ 20 9 files changed, 163 insertions(+), 151 deletions(-) 21 22diff --git a/button.c b/button.c 23index f10092a..0bbf76e 100644 24--- a/button.c 25+++ b/button.c 26@@ -2051,13 +2051,8 @@ void 27 UnmapSelections(XtermWidget xw) 28 { 29 TScreen *screen = TScreenOf(xw); 30- Cardinal n; 31 32- if (screen->mappedSelect) { 33- for (n = 0; screen->mappedSelect[n] != 0; ++n) 34- free((void *) screen->mappedSelect[n]); 35- FreeAndNull(screen->mappedSelect); 36- } 37+ FreeAndNull(screen->mappedSelect); 38 } 39 40 /* 41@@ -2093,14 +2088,11 @@ MapSelections(XtermWidget xw, String *params, Cardinal num_params) 42 if ((result = TypeMallocN(String, num_params + 1)) != 0) { 43 result[num_params] = 0; 44 for (j = 0; j < num_params; ++j) { 45- result[j] = x_strdup((isSELECT(params[j]) 46+ result[j] = (String) (isSELECT(params[j]) 47 ? mapTo 48- : params[j])); 49+ : params[j]); 50 if (result[j] == 0) { 51 UnmapSelections(xw); 52- while (j != 0) { 53- free((void *) result[--j]); 54- } 55 FreeAndNull(result); 56 break; 57 } 58diff --git a/charproc.c b/charproc.c 59index 2a3c69a..91cbcea 100644 60--- a/charproc.c 61+++ b/charproc.c 62@@ -13605,7 +13605,6 @@ DoSetSelectedFont(Widget w, 63 Bell(xw, XkbBI_MinorError, 0); 64 } else { 65 Boolean failed = False; 66- int oldFont = TScreenOf(xw)->menu_font_number; 67 char *save = TScreenOf(xw)->SelectFontName(); 68 char *val; 69 char *test; 70@@ -13650,10 +13649,6 @@ DoSetSelectedFont(Widget w, 71 failed = True; 72 } 73 if (failed) { 74- (void) xtermLoadFont(xw, 75- xtermFontName(TScreenOf(xw)->MenuFontName(oldFont)), 76- True, 77- oldFont); 78 Bell(xw, XkbBI_MinorError, 0); 79 } 80 free(used); 81@@ -13662,7 +13657,7 @@ DoSetSelectedFont(Widget w, 82 } 83 } 84 85-void 86+Bool 87 FindFontSelection(XtermWidget xw, const char *atom_name, Bool justprobe) 88 { 89 TScreen *screen = TScreenOf(xw); 90@@ -13702,7 +13697,7 @@ FindFontSelection(XtermWidget xw, const char *atom_name, Bool justprobe) 91 DoSetSelectedFont, NULL, 92 XtLastTimestampProcessed(XtDisplay(xw))); 93 } 94- return; 95+ return (screen->SelectFontName() != NULL) ? True : False; 96 } 97 98 Bool 99diff --git a/doublechr.c b/doublechr.c 100index a802e32..6416849 100644 101--- a/doublechr.c 102+++ b/doublechr.c 103@@ -295,7 +295,7 @@ xterm_DoubleGC(XTermDraw * params, GC old_gc, int *inxp) 104 temp.flags = (params->attr_flags & BOLD); 105 temp.warn = fwResource; 106 107- if (!xtermOpenFont(params->xw, name, &temp, False)) { 108+ if (!xtermOpenFont(params->xw, name, &temp, NULL, False)) { 109 XTermDraw local = *params; 110 char *nname; 111 112@@ -304,7 +304,7 @@ xterm_DoubleGC(XTermDraw * params, GC old_gc, int *inxp) 113 nname = xtermSpecialFont(&local); 114 if (nname != 0) { 115 found = (Boolean) xtermOpenFont(params->xw, nname, &temp, 116- False); 117+ NULL, False); 118 free(nname); 119 } 120 } else { 121diff --git a/fontutils.c b/fontutils.c 122index 1646b4b..71f4ec2 100644 123--- a/fontutils.c 124+++ b/fontutils.c 125@@ -92,9 +92,9 @@ 126 } 127 128 #define FREE_FNAME(field) \ 129- if (fonts == 0 || myfonts.field != fonts->field) { \ 130- FREE_STRING(myfonts.field); \ 131- myfonts.field = 0; \ 132+ if (fonts == 0 || new_fnames.field != fonts->field) { \ 133+ FREE_STRING(new_fnames.field); \ 134+ new_fnames.field = 0; \ 135 } 136 137 /* 138@@ -573,7 +573,7 @@ open_italic_font(XtermWidget xw, int n, FontNameProperties *fp, XTermFonts * dat 139 if ((name = italic_font_name(fp, slant[pass])) != 0) { 140 TRACE(("open_italic_font %s %s\n", 141 whichFontEnum((VTFontEnum) n), name)); 142- if (xtermOpenFont(xw, name, data, False)) { 143+ if (xtermOpenFont(xw, name, data, NULL, False)) { 144 result = (data->fs != 0); 145 #if OPT_REPORT_FONTS 146 if (resource.reportFonts) { 147@@ -1037,20 +1037,26 @@ xtermLoadQueryFont(XtermWidget xw, const char *name) 148 } 149 150 /* 151- * Open the given font and verify that it is non-empty. Return a null on 152+ * Open the given font and verify that it is non-empty. Return false on 153 * failure. 154 */ 155 Bool 156 xtermOpenFont(XtermWidget xw, 157 const char *name, 158 XTermFonts * result, 159+ XTermFonts * current, 160 Bool force) 161 { 162 Bool code = False; 163 164 TRACE(("xtermOpenFont %d:%d '%s'\n", 165 result->warn, xw->misc.fontWarnings, NonNull(name))); 166+ 167 if (!IsEmpty(name)) { 168+ Bool existing = (current != NULL 169+ && current->fs != NULL 170+ && current->fn != NULL); 171+ 172 if ((result->fs = xtermLoadQueryFont(xw, name)) != 0) { 173 code = True; 174 if (EmptyFont(result->fs)) { 175@@ -1069,9 +1075,13 @@ xtermOpenFont(XtermWidget xw, 176 } else { 177 TRACE(("xtermOpenFont: cannot load font '%s'\n", name)); 178 } 179- if (force) { 180+ if (existing) { 181+ TRACE(("...continue using font '%s'\n", current->fn)); 182+ result->fn = x_strdup(current->fn); 183+ result->fs = current->fs; 184+ } else if (force) { 185 NoFontWarning(result); 186- code = xtermOpenFont(xw, DEFFONT, result, True); 187+ code = xtermOpenFont(xw, DEFFONT, result, NULL, True); 188 } 189 } 190 } 191@@ -1321,6 +1331,7 @@ static Bool 192 loadNormFP(XtermWidget xw, 193 char **nameOutP, 194 XTermFonts * infoOut, 195+ XTermFonts * current, 196 int fontnum) 197 { 198 Bool status = True; 199@@ -1330,7 +1341,7 @@ loadNormFP(XtermWidget xw, 200 if (!xtermOpenFont(xw, 201 *nameOutP, 202 infoOut, 203- (fontnum == fontMenu_default))) { 204+ current, (fontnum == fontMenu_default))) { 205 /* 206 * If we are opening the default font, and it happens to be missing, 207 * force that to the compiled-in default font, e.g., "fixed". If we 208@@ -1365,10 +1376,10 @@ loadBoldFP(XtermWidget xw, 209 if (fp != 0) { 210 NoFontWarning(infoOut); 211 *nameOutP = bold_font_name(fp, fp->average_width); 212- if (!xtermOpenFont(xw, *nameOutP, infoOut, False)) { 213+ if (!xtermOpenFont(xw, *nameOutP, infoOut, NULL, False)) { 214 free(*nameOutP); 215 *nameOutP = bold_font_name(fp, -1); 216- xtermOpenFont(xw, *nameOutP, infoOut, False); 217+ xtermOpenFont(xw, *nameOutP, infoOut, NULL, False); 218 } 219 TRACE(("...derived bold '%s'\n", NonNull(*nameOutP))); 220 } 221@@ -1386,7 +1397,7 @@ loadBoldFP(XtermWidget xw, 222 TRACE(("...did not get a matching bold font\n")); 223 } 224 free(normal); 225- } else if (!xtermOpenFont(xw, *nameOutP, infoOut, False)) { 226+ } else if (!xtermOpenFont(xw, *nameOutP, infoOut, NULL, False)) { 227 xtermCopyFontInfo(infoOut, infoRef); 228 TRACE(("...cannot load bold font '%s'\n", NonNull(*nameOutP))); 229 } else { 230@@ -1440,7 +1451,7 @@ loadWideFP(XtermWidget xw, 231 } 232 233 if (check_fontname(*nameOutP)) { 234- if (xtermOpenFont(xw, *nameOutP, infoOut, False) 235+ if (xtermOpenFont(xw, *nameOutP, infoOut, NULL, False) 236 && is_derived_font_name(*nameOutP) 237 && EmptyFont(infoOut->fs)) { 238 xtermCloseFont2(xw, infoOut - fWide, fWide); 239@@ -1493,7 +1504,7 @@ loadWBoldFP(XtermWidget xw, 240 241 if (check_fontname(*nameOutP)) { 242 243- if (xtermOpenFont(xw, *nameOutP, infoOut, False) 244+ if (xtermOpenFont(xw, *nameOutP, infoOut, NULL, False) 245 && is_derived_font_name(*nameOutP) 246 && !compatibleWideCounts(wideInfoRef->fs, infoOut->fs)) { 247 xtermCloseFont2(xw, infoOut - fWBold, fWBold); 248@@ -1546,6 +1557,10 @@ loadWBoldFP(XtermWidget xw, 249 } 250 #endif 251 252+/* 253+ * Load a given bitmap font, along with the bold/wide variants. 254+ * Returns nonzero on success. 255+ */ 256 int 257 xtermLoadFont(XtermWidget xw, 258 const VTFontNames * fonts, 259@@ -1555,33 +1570,37 @@ xtermLoadFont(XtermWidget xw, 260 TScreen *screen = TScreenOf(xw); 261 VTwin *win = WhichVWin(screen); 262 263- VTFontNames myfonts; 264- XTermFonts fnts[fMAX]; 265+ VTFontNames new_fnames; 266+ XTermFonts new_fonts[fMAX]; 267+ XTermFonts old_fonts[fMAX]; 268 char *tmpname = NULL; 269 Boolean proportional = False; 270+ Boolean recovered; 271+ int code = 0; 272 273- memset(&myfonts, 0, sizeof(myfonts)); 274- memset(fnts, 0, sizeof(fnts)); 275+ memset(&new_fnames, 0, sizeof(new_fnames)); 276+ memset(new_fonts, 0, sizeof(new_fonts)); 277+ memcpy(&old_fonts, screen->fnts, sizeof(old_fonts)); 278 279 if (fonts != 0) 280- myfonts = *fonts; 281- if (!check_fontname(myfonts.f_n)) 282- return 0; 283+ new_fnames = *fonts; 284+ if (!check_fontname(new_fnames.f_n)) 285+ return code; 286 287 if (fontnum == fontMenu_fontescape 288- && myfonts.f_n != screen->MenuFontName(fontnum)) { 289- if ((tmpname = x_strdup(myfonts.f_n)) == 0) 290- return 0; 291+ && new_fnames.f_n != screen->MenuFontName(fontnum)) { 292+ if ((tmpname = x_strdup(new_fnames.f_n)) == 0) 293+ return code; 294 } 295 296- TRACE(("Begin Cgs - xtermLoadFont(%s)\n", myfonts.f_n)); 297+ TRACE(("Begin Cgs - xtermLoadFont(%s)\n", new_fnames.f_n)); 298 releaseWindowGCs(xw, win); 299 300 #define DbgResource(name, field, index) \ 301 TRACE(("xtermLoadFont #%d "name" %s%s\n", \ 302 fontnum, \ 303- (fnts[index].warn == fwResource) ? "*" : " ", \ 304- NonNull(myfonts.field))) 305+ (new_fonts[index].warn == fwResource) ? "*" : " ", \ 306+ NonNull(new_fnames.field))) 307 DbgResource("normal", f_n, fNorm); 308 DbgResource("bold ", f_b, fBold); 309 #if OPT_WIDE_CHARS 310@@ -1590,16 +1609,17 @@ xtermLoadFont(XtermWidget xw, 311 #endif 312 313 if (!loadNormFP(xw, 314- &myfonts.f_n, 315- &fnts[fNorm], 316+ &new_fnames.f_n, 317+ &new_fonts[fNorm], 318+ &old_fonts[fNorm], 319 fontnum)) 320 goto bad; 321 322 if (!loadBoldFP(xw, 323- &myfonts.f_b, 324- &fnts[fBold], 325- myfonts.f_n, 326- &fnts[fNorm], 327+ &new_fnames.f_b, 328+ &new_fonts[fBold], 329+ new_fnames.f_n, 330+ &new_fonts[fNorm], 331 fontnum)) 332 goto bad; 333 334@@ -1611,20 +1631,20 @@ xtermLoadFont(XtermWidget xw, 335 if_OPT_WIDE_CHARS(screen, { 336 337 if (!loadWideFP(xw, 338- &myfonts.f_w, 339- &fnts[fWide], 340- myfonts.f_n, 341- &fnts[fNorm], 342+ &new_fnames.f_w, 343+ &new_fonts[fWide], 344+ new_fnames.f_n, 345+ &new_fonts[fNorm], 346 fontnum)) 347 goto bad; 348 349 if (!loadWBoldFP(xw, 350- &myfonts.f_wb, 351- &fnts[fWBold], 352- myfonts.f_w, 353- &fnts[fWide], 354- myfonts.f_b, 355- &fnts[fBold], 356+ &new_fnames.f_wb, 357+ &new_fonts[fWBold], 358+ new_fnames.f_w, 359+ &new_fonts[fWide], 360+ new_fnames.f_b, 361+ &new_fonts[fBold], 362 fontnum)) 363 goto bad; 364 365@@ -1634,30 +1654,30 @@ xtermLoadFont(XtermWidget xw, 366 * Normal/bold fonts should be the same width. Also, the min/max 367 * values should be the same. 368 */ 369- if (fnts[fNorm].fs != 0 370- && fnts[fBold].fs != 0 371- && (!is_fixed_font(fnts[fNorm].fs) 372- || !is_fixed_font(fnts[fBold].fs) 373- || differing_widths(fnts[fNorm].fs, fnts[fBold].fs))) { 374+ if (new_fonts[fNorm].fs != 0 375+ && new_fonts[fBold].fs != 0 376+ && (!is_fixed_font(new_fonts[fNorm].fs) 377+ || !is_fixed_font(new_fonts[fBold].fs) 378+ || differing_widths(new_fonts[fNorm].fs, new_fonts[fBold].fs))) { 379 TRACE(("Proportional font! normal %d/%d, bold %d/%d\n", 380- fnts[fNorm].fs->min_bounds.width, 381- fnts[fNorm].fs->max_bounds.width, 382- fnts[fBold].fs->min_bounds.width, 383- fnts[fBold].fs->max_bounds.width)); 384+ new_fonts[fNorm].fs->min_bounds.width, 385+ new_fonts[fNorm].fs->max_bounds.width, 386+ new_fonts[fBold].fs->min_bounds.width, 387+ new_fonts[fBold].fs->max_bounds.width)); 388 proportional = True; 389 } 390 391 if_OPT_WIDE_CHARS(screen, { 392- if (fnts[fWide].fs != 0 393- && fnts[fWBold].fs != 0 394- && (!is_fixed_font(fnts[fWide].fs) 395- || !is_fixed_font(fnts[fWBold].fs) 396- || differing_widths(fnts[fWide].fs, fnts[fWBold].fs))) { 397+ if (new_fonts[fWide].fs != 0 398+ && new_fonts[fWBold].fs != 0 399+ && (!is_fixed_font(new_fonts[fWide].fs) 400+ || !is_fixed_font(new_fonts[fWBold].fs) 401+ || differing_widths(new_fonts[fWide].fs, new_fonts[fWBold].fs))) { 402 TRACE(("Proportional font! wide %d/%d, wide bold %d/%d\n", 403- fnts[fWide].fs->min_bounds.width, 404- fnts[fWide].fs->max_bounds.width, 405- fnts[fWBold].fs->min_bounds.width, 406- fnts[fWBold].fs->max_bounds.width)); 407+ new_fonts[fWide].fs->min_bounds.width, 408+ new_fonts[fWide].fs->max_bounds.width, 409+ new_fonts[fWBold].fs->min_bounds.width, 410+ new_fonts[fWBold].fs->max_bounds.width)); 411 proportional = True; 412 } 413 }); 414@@ -1676,13 +1696,13 @@ xtermLoadFont(XtermWidget xw, 415 screen->ifnts_ok = False; 416 #endif 417 418- xtermCopyFontInfo(GetNormalFont(screen, fNorm), &fnts[fNorm]); 419- xtermCopyFontInfo(GetNormalFont(screen, fBold), &fnts[fBold]); 420+ xtermCopyFontInfo(GetNormalFont(screen, fNorm), &new_fonts[fNorm]); 421+ xtermCopyFontInfo(GetNormalFont(screen, fBold), &new_fonts[fBold]); 422 #if OPT_WIDE_CHARS 423- xtermCopyFontInfo(GetNormalFont(screen, fWide), &fnts[fWide]); 424- if (fnts[fWBold].fs == NULL) 425- xtermCopyFontInfo(GetNormalFont(screen, fWide), &fnts[fWide]); 426- xtermCopyFontInfo(GetNormalFont(screen, fWBold), &fnts[fWBold]); 427+ xtermCopyFontInfo(GetNormalFont(screen, fWide), &new_fonts[fWide]); 428+ if (new_fonts[fWBold].fs == NULL) 429+ xtermCopyFontInfo(GetNormalFont(screen, fWide), &new_fonts[fWide]); 430+ xtermCopyFontInfo(GetNormalFont(screen, fWBold), &new_fonts[fWBold]); 431 #endif 432 433 xtermUpdateFontGCs(xw, getNormalFont); 434@@ -1713,7 +1733,7 @@ xtermLoadFont(XtermWidget xw, 435 unsigned ch; 436 437 #if OPT_TRACE 438-#define TRACE_MISS(index) show_font_misses(#index, &fnts[index]) 439+#define TRACE_MISS(index) show_font_misses(#index, &new_fonts[index]) 440 TRACE_MISS(fNorm); 441 TRACE_MISS(fBold); 442 #if OPT_WIDE_CHARS 443@@ -1730,8 +1750,8 @@ xtermLoadFont(XtermWidget xw, 444 if ((n != UCS_REPL) 445 && (n != ch) 446 && (screen->fnt_boxes & 2)) { 447- if (xtermMissingChar(n, &fnts[fNorm]) || 448- xtermMissingChar(n, &fnts[fBold])) { 449+ if (xtermMissingChar(n, &new_fonts[fNorm]) || 450+ xtermMissingChar(n, &new_fonts[fBold])) { 451 UIntClr(screen->fnt_boxes, 2); 452 TRACE(("missing graphics character #%d, U+%04X\n", 453 ch, n)); 454@@ -1743,12 +1763,12 @@ xtermLoadFont(XtermWidget xw, 455 #endif 456 457 for (ch = 1; ch < 32; ch++) { 458- if (xtermMissingChar(ch, &fnts[fNorm])) { 459+ if (xtermMissingChar(ch, &new_fonts[fNorm])) { 460 TRACE(("missing normal char #%d\n", ch)); 461 UIntClr(screen->fnt_boxes, 1); 462 break; 463 } 464- if (xtermMissingChar(ch, &fnts[fBold])) { 465+ if (xtermMissingChar(ch, &new_fonts[fBold])) { 466 TRACE(("missing bold char #%d\n", ch)); 467 UIntClr(screen->fnt_boxes, 1); 468 break; 469@@ -1765,8 +1785,8 @@ xtermLoadFont(XtermWidget xw, 470 screen->enbolden = screen->bold_mode; 471 } else { 472 screen->enbolden = screen->bold_mode 473- && ((fnts[fNorm].fs == fnts[fBold].fs) 474- || same_font_name(myfonts.f_n, myfonts.f_b)); 475+ && ((new_fonts[fNorm].fs == new_fonts[fBold].fs) 476+ || same_font_name(new_fnames.f_n, new_fnames.f_b)); 477 } 478 TRACE(("Will %suse 1-pixel offset/overstrike to simulate bold\n", 479 screen->enbolden ? "" : "not ")); 480@@ -1782,7 +1802,7 @@ xtermLoadFont(XtermWidget xw, 481 update_font_escape(); 482 } 483 #if OPT_SHIFT_FONTS 484- screen->menu_font_sizes[fontnum] = FontSize(fnts[fNorm].fs); 485+ screen->menu_font_sizes[fontnum] = FontSize(new_fonts[fNorm].fs); 486 #endif 487 } 488 set_cursor_gcs(xw); 489@@ -1797,20 +1817,21 @@ xtermLoadFont(XtermWidget xw, 490 FREE_FNAME(f_w); 491 FREE_FNAME(f_wb); 492 #endif 493- if (fnts[fNorm].fn == fnts[fBold].fn) { 494- free(fnts[fNorm].fn); 495+ if (new_fonts[fNorm].fn == new_fonts[fBold].fn) { 496+ free(new_fonts[fNorm].fn); 497 } else { 498- free(fnts[fNorm].fn); 499- free(fnts[fBold].fn); 500+ free(new_fonts[fNorm].fn); 501+ free(new_fonts[fBold].fn); 502 } 503 #if OPT_WIDE_CHARS 504- free(fnts[fWide].fn); 505- free(fnts[fWBold].fn); 506+ free(new_fonts[fWide].fn); 507+ free(new_fonts[fWBold].fn); 508 #endif 509 xtermSetWinSize(xw); 510 return 1; 511 512 bad: 513+ recovered = False; 514 free(tmpname); 515 516 #if OPT_RENDERFONT 517@@ -1820,15 +1841,15 @@ xtermLoadFont(XtermWidget xw, 518 SetItemSensitivity(fontMenuEntries[fontnum].widget, True); 519 #endif 520 Bell(xw, XkbBI_MinorError, 0); 521- myfonts.f_n = screen->MenuFontName(old_fontnum); 522- return xtermLoadFont(xw, &myfonts, doresize, old_fontnum); 523- } else if (x_strcasecmp(myfonts.f_n, DEFFONT)) { 524- int code; 525- 526- myfonts.f_n = x_strdup(DEFFONT); 527- TRACE(("...recovering for TrueType fonts\n")); 528- code = xtermLoadFont(xw, &myfonts, doresize, fontnum); 529- if (code) { 530+ new_fnames.f_n = screen->MenuFontName(old_fontnum); 531+ if (xtermLoadFont(xw, &new_fnames, doresize, old_fontnum)) 532+ recovered = True; 533+ } else if (x_strcasecmp(new_fnames.f_n, DEFFONT) 534+ && x_strcasecmp(new_fnames.f_n, old_fonts[fNorm].fn)) { 535+ new_fnames.f_n = x_strdup(old_fonts[fNorm].fn); 536+ TRACE(("...recovering from failed font-load\n")); 537+ if (xtermLoadFont(xw, &new_fnames, doresize, fontnum)) { 538+ recovered = True; 539 if (fontnum != fontMenu_fontsel) { 540 SetItemSensitivity(fontMenuEntries[fontnum].widget, 541 UsingRenderFont(xw)); 542@@ -1837,15 +1858,15 @@ xtermLoadFont(XtermWidget xw, 543 FontHeight(screen), 544 FontWidth(screen))); 545 } 546- return code; 547 } 548 #endif 549- 550- releaseWindowGCs(xw, win); 551- 552- xtermCloseFonts(xw, fnts); 553- TRACE(("Fail Cgs - xtermLoadFont\n")); 554- return 0; 555+ if (!recovered) { 556+ releaseWindowGCs(xw, win); 557+ xtermCloseFonts(xw, new_fonts); 558+ TRACE(("Fail Cgs - xtermLoadFont\n")); 559+ code = 0; 560+ } 561+ return code; 562 } 563 564 #if OPT_WIDE_ATTRS 565@@ -1893,7 +1914,7 @@ xtermLoadItalics(XtermWidget xw) 566 } else { 567 xtermOpenFont(xw, 568 getNormalFont(screen, n)->fn, 569- data, False); 570+ data, NULL, False); 571 } 572 } 573 } 574@@ -4250,6 +4271,8 @@ findXftGlyph(XtermWidget xw, XftFont *given, unsigned wc) 575 } 576 #endif 577 if (foundXftGlyph(xw, check, wc)) { 578+ (void) added; 579+ (void) actual; 580 markXftOpened(xw, which, n, wc); 581 reportXftFonts(xw, check, "fallback", tag, myReport); 582 result = check; 583@@ -4451,7 +4474,7 @@ lookupOneFontSize(XtermWidget xw, int fontnum) 584 585 memset(&fnt, 0, sizeof(fnt)); 586 screen->menu_font_sizes[fontnum] = -1; 587- if (xtermOpenFont(xw, screen->MenuFontName(fontnum), &fnt, True)) { 588+ if (xtermOpenFont(xw, screen->MenuFontName(fontnum), &fnt, NULL, True)) { 589 if (fontnum <= fontMenu_lastBuiltin 590 || strcmp(fnt.fn, DEFFONT)) { 591 screen->menu_font_sizes[fontnum] = FontSize(fnt.fs); 592@@ -4864,13 +4887,14 @@ HandleSetFont(Widget w, 593 } 594 } 595 596-void 597+Bool 598 SetVTFont(XtermWidget xw, 599 int which, 600 Bool doresize, 601 const VTFontNames * fonts) 602 { 603 TScreen *screen = TScreenOf(xw); 604+ Bool result = False; 605 606 TRACE(("SetVTFont(which=%d, f_n=%s, f_b=%s)\n", which, 607 (fonts && fonts->f_n) ? fonts->f_n : "<null>", 608@@ -4879,34 +4903,31 @@ SetVTFont(XtermWidget xw, 609 if (IsIcon(screen)) { 610 Bell(xw, XkbBI_MinorError, 0); 611 } else if (which >= 0 && which < NMENUFONTS) { 612- VTFontNames myfonts; 613+ VTFontNames new_fnames; 614 615- memset(&myfonts, 0, sizeof(myfonts)); 616+ memset(&new_fnames, 0, sizeof(new_fnames)); 617 if (fonts != 0) 618- myfonts = *fonts; 619+ new_fnames = *fonts; 620 621 if (which == fontMenu_fontsel) { /* go get the selection */ 622- FindFontSelection(xw, myfonts.f_n, False); 623+ result = FindFontSelection(xw, new_fnames.f_n, False); 624 } else { 625- int oldFont = screen->menu_font_number; 626- 627 #define USE_CACHED(field, name) \ 628- if (myfonts.field == 0) { \ 629- myfonts.field = x_strdup(screen->menu_font_names[which][name]); \ 630- TRACE(("set myfonts." #field " from menu_font_names[%d][" #name "] %s\n", \ 631- which, NonNull(myfonts.field))); \ 632+ if (new_fnames.field == NULL) { \ 633+ new_fnames.field = x_strdup(screen->menu_font_names[which][name]); \ 634+ TRACE(("set new_fnames." #field " from menu_font_names[%d][" #name "] %s\n", \ 635+ which, NonNull(new_fnames.field))); \ 636 } else { \ 637- TRACE(("set myfonts." #field " reused\n")); \ 638+ TRACE(("set new_fnames." #field " reused\n")); \ 639 } 640 #define SAVE_FNAME(field, name) \ 641- if (myfonts.field != 0) { \ 642- if (screen->menu_font_names[which][name] == 0 \ 643- || strcmp(screen->menu_font_names[which][name], myfonts.field)) { \ 644- TRACE(("updating menu_font_names[%d][" #name "] to \"%s\"\n", \ 645- which, myfonts.field)); \ 646- FREE_STRING(screen->menu_font_names[which][name]); \ 647- screen->menu_font_names[which][name] = x_strdup(myfonts.field); \ 648- } \ 649+ if (new_fnames.field != NULL \ 650+ && (screen->menu_font_names[which][name] == NULL \ 651+ || strcmp(screen->menu_font_names[which][name], new_fnames.field))) { \ 652+ TRACE(("updating menu_font_names[%d][" #name "] to \"%s\"\n", \ 653+ which, new_fnames.field)); \ 654+ FREE_STRING(screen->menu_font_names[which][name]); \ 655+ screen->menu_font_names[which][name] = x_strdup(new_fnames.field); \ 656 } 657 658 USE_CACHED(f_n, fNorm); 659@@ -4916,7 +4937,7 @@ SetVTFont(XtermWidget xw, 660 USE_CACHED(f_wb, fWBold); 661 #endif 662 if (xtermLoadFont(xw, 663- &myfonts, 664+ &new_fnames, 665 doresize, which)) { 666 /* 667 * If successful, save the data so that a subsequent query via 668@@ -4928,10 +4949,8 @@ SetVTFont(XtermWidget xw, 669 SAVE_FNAME(f_w, fWide); 670 SAVE_FNAME(f_wb, fWBold); 671 #endif 672+ result = True; 673 } else { 674- (void) xtermLoadFont(xw, 675- xtermFontName(screen->MenuFontName(oldFont)), 676- doresize, oldFont); 677 Bell(xw, XkbBI_MinorError, 0); 678 } 679 FREE_FNAME(f_n); 680@@ -4944,7 +4963,8 @@ SetVTFont(XtermWidget xw, 681 } else { 682 Bell(xw, XkbBI_MinorError, 0); 683 } 684- return; 685+ TRACE(("...SetVTFont: %d\n", result)); 686+ return result; 687 } 688 689 #if OPT_RENDERFONT 690diff --git a/fontutils.h b/fontutils.h 691index 2267f24..5b3afe0 100644 692--- a/fontutils.h 693+++ b/fontutils.h 694@@ -37,7 +37,7 @@ 695 /* *INDENT-OFF* */ 696 697 extern Bool xtermLoadDefaultFonts (XtermWidget /* xw */); 698-extern Bool xtermOpenFont (XtermWidget /* xw */, const char */* name */, XTermFonts * /* result */, Bool /* force */); 699+extern Bool xtermOpenFont (XtermWidget /* xw */, const char */* name */, XTermFonts * /* result */, XTermFonts * /* current */, Bool /* force */); 700 extern XFontStruct * xtermLoadQueryFont(XtermWidget /* xw */, const char * /*name */); 701 extern XTermFonts * getDoubleFont (TScreen * /* screen */, int /* which */); 702 extern XTermFonts * getItalicFont (TScreen * /* screen */, int /* which */); 703@@ -51,7 +51,7 @@ extern int lookupRelativeFontSize (XtermWidget /* xw */, int /* old */, int /* r 704 extern int xtermGetFont (const char * /* param */); 705 extern int xtermLoadFont (XtermWidget /* xw */, const VTFontNames */* fonts */, Bool /* doresize */, int /* fontnum */); 706 extern void HandleSetFont PROTO_XT_ACTIONS_ARGS; 707-extern void SetVTFont (XtermWidget /* xw */, int /* i */, Bool /* doresize */, const VTFontNames */* fonts */); 708+extern Bool SetVTFont (XtermWidget /* xw */, int /* i */, Bool /* doresize */, const VTFontNames */* fonts */); 709 extern void allocFontList (XtermWidget /* xw */, const char * /* name */, XtermFontNames * /* target */, VTFontEnum /* which */, const char * /* source */, Bool /* ttf */); 710 extern void copyFontList (char *** /* targetp */, char ** /* source */); 711 extern void initFontLists (XtermWidget /* xw */); 712diff --git a/misc.c b/misc.c 713index cbb2679..aafbb08 100644 714--- a/misc.c 715+++ b/misc.c 716@@ -3941,9 +3941,9 @@ ChangeFontRequest(XtermWidget xw, String buf) 717 { 718 memset(&fonts, 0, sizeof(fonts)); 719 fonts.f_n = name; 720- SetVTFont(xw, num, True, &fonts); 721- if (num == screen->menu_font_number && 722- num != fontMenu_fontescape) { 723+ if (SetVTFont(xw, num, True, &fonts) 724+ && num == screen->menu_font_number 725+ && num != fontMenu_fontescape) { 726 screen->EscapeFontName() = x_strdup(name); 727 } 728 } 729@@ -6422,7 +6422,6 @@ xtermSetenv(const char *var, const char *value) 730 731 found = envindex; 732 environ[found + 1] = NULL; 733- environ = environ; 734 } 735 736 environ[found] = malloc(2 + len + strlen(value)); 737diff --git a/screen.c b/screen.c 738index 93e36b3..f82ee44 100644 739--- a/screen.c 740+++ b/screen.c 741@@ -1454,7 +1454,7 @@ ScrnRefresh(XtermWidget xw, 742 maxrow += StatusLineRows; 743 } 744 #endif 745- 746+ (void) recurse; 747 ++recurse; 748 749 if (screen->cursorp.col >= leftcol 750diff --git a/xterm.h b/xterm.h 751index e6bd123..c4fe811 100644 752--- a/xterm.h 753+++ b/xterm.h 754@@ -999,7 +999,7 @@ extern Bool CheckBufPtrs (TScreen * /* screen */); 755 extern Bool set_cursor_gcs (XtermWidget /* xw */); 756 extern char * vt100ResourceToString (XtermWidget /* xw */, const char * /* name */); 757 extern int VTInit (XtermWidget /* xw */); 758-extern void FindFontSelection (XtermWidget /* xw */, const char * /* atom_name */, Bool /* justprobe */); 759+extern Bool FindFontSelection (XtermWidget /* xw */, const char * /* atom_name */, Bool /* justprobe */); 760 extern void HideCursor (XtermWidget /* xw */); 761 extern void RestartBlinking(XtermWidget /* xw */); 762 extern void ShowCursor (XtermWidget /* xw */); 763diff --git a/xterm.log.html b/xterm.log.html 764index 03324b1..0f28658 100644 765--- a/xterm.log.html 766+++ b/xterm.log.html 767@@ -1026,6 +1026,12 @@ 768 2022/03/09</a></h1> 769 770 <ul> 771+ <li>improve error-recovery when setting a bitmap font for the 772+ VT100 window, e.g., in case <em>OSC 50</em> failed, 773+ restoring the most recent valid font so that a subsequent 774+ <em>OSC 50</em> reports this correctly (report by David 775+ Leadbeater).</li> 776+ 777 <li>amend allocation/freeing of scrollback lines, eliminating 778 an adjustment for status-line added in <a href= 779 "#xterm_371">patch #371</a> (report/testcase by Rajeev V. 780-- 7812.25.1 782 783