File xterm-CVE-2022-45063.patch of Package xterm.27929

From 787636674918873a091e7a4ef5977263ba982322 Mon Sep 17 00:00:00 2001
From: "Thomas E. Dickey" <dickey@invisible-island.net>
Date: Sun, 23 Oct 2022 22:59:52 +0000
Subject: [PATCH] snapshot of project "xterm", label xterm-374c

---
 MANIFEST       |   2 +-
 button.c       |  16 +--
 charproc.c     |  11 +-
 doublechr.c    |   6 +-
 fontutils.c    | 272 ++++++++++++++++++++++++++-----------------------
 fontutils.h    |   6 +-
 misc.c         |   9 +-
 screen.c       |   4 +-
 xterm.h        |   4 +-
 xterm.log.html |   8 +-
 10 files changed, 174 insertions(+), 164 deletions(-)

Index: xterm-308/button.c
===================================================================
--- xterm-308.orig/button.c
+++ xterm-308/button.c
@@ -1555,8 +1555,6 @@ UnmapSelections(XtermWidget xw)
     Cardinal n;
 
     if (screen->mappedSelect) {
-	for (n = 0; screen->mappedSelect[n] != 0; ++n)
-	    free((void *) screen->mappedSelect[n]);
 	free(screen->mappedSelect);
 	screen->mappedSelect = 0;
     }
@@ -1595,14 +1593,11 @@ MapSelections(XtermWidget xw, String *pa
 	    if ((result = TypeMallocN(String, num_params + 1)) != 0) {
 		result[num_params] = 0;
 		for (j = 0; j < num_params; ++j) {
-		    result[j] = x_strdup((isSELECT(params[j])
+		    result[j] = (String)(isSELECT(params[j])
 					  ? mapTo
-					  : params[j]));
+					  : params[j]);
 		    if (result[j] == 0) {
 			UnmapSelections(xw);
-			while (j != 0) {
-			    free((void *) result[--j]);
-			}
 			free(result);
 			result = 0;
 			break;
Index: xterm-308/charproc.c
===================================================================
--- xterm-308.orig/charproc.c
+++ xterm-308/charproc.c
@@ -10750,7 +10750,6 @@ DoSetSelectedFont(Widget w,
 	Bell(xw, XkbBI_MinorError, 0);
     } else {
 	Boolean failed = False;
-	int oldFont = TScreenOf(xw)->menu_font_number;
 	String save = TScreenOf(xw)->MenuFontName(fontMenu_fontsel);
 	char *val;
 	char *test = 0;
@@ -10794,10 +10793,6 @@ DoSetSelectedFont(Widget w,
 		failed = True;
 	    }
 	    if (failed) {
-		(void) xtermLoadFont(term,
-				     xtermFontName(TScreenOf(xw)->MenuFontName(oldFont)),
-				     True,
-				     oldFont);
 		Bell(xw, XkbBI_MinorError, 0);
 	    }
 	    free(used);
@@ -10806,7 +10801,7 @@ DoSetSelectedFont(Widget w,
     }
 }
 
-void
+Bool
 FindFontSelection(XtermWidget xw, const char *atom_name, Bool justprobe)
 {
     TScreen *screen = TScreenOf(xw);
@@ -10846,7 +10841,8 @@ FindFontSelection(XtermWidget xw, const
 			    DoSetSelectedFont, NULL,
 			    XtLastTimestampProcessed(XtDisplay(xw)));
     }
-    return;
+    
+    return (screen->MenuFontName(fontMenu_fontsel) != NULL) ? True : False;
 }
 
 Bool
Index: xterm-308/doublechr.c
===================================================================
--- xterm-308.orig/doublechr.c
+++ xterm-308/doublechr.c
@@ -294,7 +294,7 @@ xterm_DoubleGC(XtermWidget xw,
 	    temp.chrset = chrset;
 	    temp.flags = (attr_flags & BOLD);
 
-	    if (!xtermOpenFont(xw, name, &temp, fwAlways, False)) {
+	    if (!xtermOpenFont(xw, name, &temp, fwAlways, NULL, False)) {
 		/* Retry with * in resolutions */
 		char *nname = xtermSpecialFont(screen,
 					       attr_flags,
@@ -303,7 +303,7 @@ xterm_DoubleGC(XtermWidget xw,
 
 		if (nname != 0) {
 		    found = (Boolean) xtermOpenFont(xw, nname, &temp,
-						    fwAlways, False);
+						    fwAlways, NULL, False);
 		    free(nname);
 		}
 	    } else {
Index: xterm-308/fontutils.c
===================================================================
--- xterm-308.orig/fontutils.c
+++ xterm-308/fontutils.c
@@ -96,9 +96,9 @@
 }
 
 #define FREE_FNAME(field) \
-	    if (fonts == 0 || myfonts.field != fonts->field) { \
-		FREE_STRING(myfonts.field); \
-		myfonts.field = 0; \
+	    if (fonts == 0 || new_fnames.field != fonts->field) { \
+		FREE_STRING(new_fnames.field); \
+		new_fnames.field = 0; \
 	    }
 
 /*
@@ -769,12 +769,17 @@ xtermOpenFont(XtermWidget xw,
 	      const char *name,
 	      XTermFonts * result,
 	      fontWarningTypes warn,
+	      XTermFonts * current,
 	      Bool force)
 {
     Bool code = False;
     TScreen *screen = TScreenOf(xw);
 
     if (!IsEmpty(name)) {
+	Bool existing = (current != NULL
+		&& current->fs != NULL
+		&& current->fn != NULL);
+
 	if ((result->fs = XLoadQueryFont(screen->display, name)) != 0) {
 	    code = True;
 	    if (EmptyFont(result->fs)) {
@@ -804,8 +809,12 @@ xtermOpenFont(XtermWidget xw,
 	    } else {
 		TRACE(("xtermOpenFont: cannot load font '%s'\n", name));
 	    }
-	    if (force) {
-		code = xtermOpenFont(xw, DEFFONT, result, fwAlways, True);
+	    if (existing) {
+		TRACE(("...continue using font '%s'\n", current->fn));
+		result->fn = x_strdup(current->fn);
+		result->fs = current->fs;
+	    } else if (force) {
+		code = xtermOpenFont(xw, DEFFONT, result, fwAlways, NULL, True);
 	    }
 	}
     }
@@ -1019,31 +1028,41 @@ show_font_misses(const char *name, XTerm
 }
 #endif
 
+/*
+ * Load a given bitmap font, along with the bold/wide variants.
+ * Returns nonzero on success.
+ */
 int
 xtermLoadFont(XtermWidget xw,
 	      const VTFontNames * fonts,
 	      Bool doresize,
-	      int fontnum)
+	      int fontnum
+	      )
 {
     TScreen *screen = TScreenOf(xw);
     VTwin *win = WhichVWin(screen);
 
-    VTFontNames myfonts;
+    VTFontNames new_fnames;
     FontNameProperties *fp;
-    XTermFonts fnts[fMAX];
+    XTermFonts new_fnts[fMAX];
+    XTermFonts old_fnts[fMAX];
     char *tmpname = NULL;
     char *normal = NULL;
     Boolean proportional = False;
     fontWarningTypes warn[fMAX];
     int j;
+    Boolean recovered;
+    int code = 0;
 
-    memset(&myfonts, 0, sizeof(myfonts));
-    memset(fnts, 0, sizeof(fnts));
+
+    memset(&new_fnames, 0, sizeof(new_fnames));
+    memset(new_fnts, 0, sizeof(new_fnts));
+    memcpy(&old_fnts, screen->fnts, sizeof(old_fnts));
 
     if (fonts != 0)
-	myfonts = *fonts;
-    if (!check_fontname(myfonts.f_n))
-	return 0;
+	new_fnames = *fonts;
+    if (!check_fontname(new_fnames.f_n))
+	return code;
 
     /*
      * Check the font names against the resource values, to see which were
@@ -1054,7 +1073,7 @@ xtermLoadFont(XtermWidget xw,
 	warn[j] = fwAlways;
     }
 #define CmpResource(field, index) \
-    if (same_font_name(screen->menu_font_names[fontnum][index], myfonts.field)) \
+    if (same_font_name(screen->menu_font_names[fontnum][index], new_fnames.field)) \
 	warn[index] = fwResource
 
     CmpResource(f_n, fNorm);
@@ -1067,19 +1086,19 @@ xtermLoadFont(XtermWidget xw,
     }
 
     if (fontnum == fontMenu_fontescape
-	&& myfonts.f_n != screen->MenuFontName(fontnum)) {
-	if ((tmpname = x_strdup(myfonts.f_n)) == 0)
-	    return 0;
+	&& new_fnames.f_n != screen->MenuFontName(fontnum)) {
+	if ((tmpname = x_strdup(new_fnames.f_n)) == 0)
+	    return code;
     }
 
-    TRACE(("Begin Cgs - xtermLoadFont(%s)\n", myfonts.f_n));
+    TRACE(("Begin Cgs - xtermLoadFont(%s)\n", new_fnames.f_n));
     releaseWindowGCs(xw, win);
 
 #define DbgResource(name, field, index) \
     TRACE(("xtermLoadFont #%d "name" %s%s\n", \
     	   fontnum, \
 	   (warn[index] == fwResource) ? "*" : " ", \
-	   NonNull(myfonts.field)))
+	   NonNull(new_fnames.field)))
     DbgResource("normal", f_n, fNorm);
     DbgResource("bold  ", f_b, fBold);
 #if OPT_WIDE_CHARS
@@ -1093,47 +1112,48 @@ xtermLoadFont(XtermWidget xw,
      * the font, disable it from the menu.
      */
     if (!xtermOpenFont(xw,
-		       myfonts.f_n,
-		       &fnts[fNorm],
+		       new_fnames.f_n,
+		       &new_fnts[fNorm],
 		       warn[fNorm],
+		       &old_fnts[fNorm],
 		       (fontnum == fontMenu_default))) {
 	SetItemSensitivity(fontMenuEntries[fontnum].widget, False);
 	goto bad;
     }
 
-    normal = x_strdup(myfonts.f_n);
-    if (!check_fontname(myfonts.f_b)) {
+    normal = x_strdup(new_fnames.f_n);
+    if (!check_fontname(new_fnames.f_b)) {
 	warn[fBold] = fwAlways;
-	fp = get_font_name_props(screen->display, fnts[fNorm].fs, &normal);
+	fp = get_font_name_props(screen->display, new_fnts[fNorm].fs, &normal);
 	if (fp != 0) {
 	    FREE_FNAME(f_b);
-	    myfonts.f_b = bold_font_name(fp, fp->average_width);
-	    if (!xtermOpenFont(xw, myfonts.f_b, &fnts[fBold], fwAlways, False)) {
+	    new_fnames.f_b = bold_font_name(fp, fp->average_width);
+	    if (!xtermOpenFont(xw, new_fnames.f_b, &new_fnts[fBold], fwAlways, NULL, False)) {
 		FREE_FNAME(f_b);
-		myfonts.f_b = bold_font_name(fp, -1);
-		xtermOpenFont(xw, myfonts.f_b, &fnts[fBold], fwAlways, False);
+		new_fnames.f_b = bold_font_name(fp, -1);
+		xtermOpenFont(xw, new_fnames.f_b, &new_fnts[fBold], fwAlways, NULL, False);
 	    }
-	    TRACE(("...derived bold '%s'\n", NonNull(myfonts.f_b)));
+	    TRACE(("...derived bold '%s'\n", NonNull(new_fnames.f_b)));
 	}
-	if (fp == 0 || fnts[fBold].fs == 0) {
-	    xtermCopyFontInfo(&fnts[fBold], &fnts[fNorm]);
+	if (fp == 0 || new_fnts[fBold].fs == 0) {
+	    xtermCopyFontInfo(&new_fnts[fBold], &new_fnts[fNorm]);
 	    TRACE(("...cannot load a matching bold font\n"));
-	} else if (comparable_metrics(fnts[fNorm].fs, fnts[fBold].fs)
-		   && same_font_size(xw, fnts[fNorm].fs, fnts[fBold].fs)
-		   && got_bold_font(screen->display, fnts[fBold].fs, myfonts.f_b)) {
+	} else if (comparable_metrics(new_fnts[fNorm].fs, new_fnts[fBold].fs)
+		   && same_font_size(xw, new_fnts[fNorm].fs, new_fnts[fBold].fs)
+		   && got_bold_font(screen->display, new_fnts[fBold].fs, new_fnames.f_b)) {
 	    TRACE(("...got a matching bold font\n"));
-	    cache_menu_font_name(screen, fontnum, fBold, myfonts.f_b);
+	    cache_menu_font_name(screen, fontnum, fBold, new_fnames.f_b);
 	} else {
-	    xtermCloseFont(xw, &fnts[fBold]);
-	    fnts[fBold] = fnts[fNorm];
+	    xtermCloseFont(xw, &new_fnts[fBold]);
+	    new_fnts[fBold] = new_fnts[fNorm];
 	    TRACE(("...did not get a matching bold font\n"));
 	}
-    } else if (!xtermOpenFont(xw, myfonts.f_b, &fnts[fBold], warn[fBold], False)) {
-	xtermCopyFontInfo(&fnts[fBold], &fnts[fNorm]);
+    } else if (!xtermOpenFont(xw, new_fnames.f_b, &new_fnts[fBold], warn[fBold], NULL, False)) {
+	xtermCopyFontInfo(&new_fnts[fBold], &new_fnts[fNorm]);
 	warn[fBold] = fwAlways;
-	TRACE(("...cannot load bold font '%s'\n", NonNull(myfonts.f_b)));
+	TRACE(("...cannot load bold font '%s'\n", NonNull(new_fnames.f_b)));
     } else {
-	cache_menu_font_name(screen, fontnum, fBold, myfonts.f_b);
+	cache_menu_font_name(screen, fontnum, fBold, new_fnames.f_b);
     }
 
     /*
@@ -1145,84 +1165,85 @@ xtermLoadFont(XtermWidget xw,
 	Boolean derived;
 	char *bold = NULL;
 
-	if (check_fontname(myfonts.f_w)) {
-	    cache_menu_font_name(screen, fontnum, fWide, myfonts.f_w);
-	} else if (screen->utf8_fonts && !is_double_width_font(fnts[fNorm].fs)) {
+	if (check_fontname(new_fnames.f_w)) {
+	    cache_menu_font_name(screen, fontnum, fWide, new_fnames.f_w);
+	} else if (screen->utf8_fonts && !is_double_width_font(new_fnts[fNorm].fs)) {
 	    FREE_FNAME(f_w);
-	    fp = get_font_name_props(screen->display, fnts[fNorm].fs, &normal);
+	    fp = get_font_name_props(screen->display, new_fnts[fNorm].fs, &normal);
 	    if (fp != 0) {
-		myfonts.f_w = wide_font_name(fp);
+		new_fnames.f_w = wide_font_name(fp);
 		warn[fWide] = fwAlways;
-		TRACE(("...derived wide %s\n", NonNull(myfonts.f_w)));
-		cache_menu_font_name(screen, fontnum, fWide, myfonts.f_w);
+		TRACE(("...derived wide %s\n", NonNull(new_fnames.f_w)));
+		cache_menu_font_name(screen, fontnum, fWide, new_fnames.f_w);
 	    }
 	}
 
-	if (check_fontname(myfonts.f_w)) {
-	    (void) xtermOpenFont(xw, myfonts.f_w, &fnts[fWide], warn[fWide], False);
+	if (check_fontname(new_fnames.f_w)) {
+	    (void) xtermOpenFont(xw, new_fnames.f_w, &new_fnts[fWide], warn[fWide], NULL, False);
 	} else {
-	    xtermCopyFontInfo(&fnts[fWide], &fnts[fNorm]);
+	    xtermCopyFontInfo(&new_fnts[fWide], &new_fnts[fNorm]);
 	    warn[fWide] = fwAlways;
 	}
 
 	derived = False;
-	if (!check_fontname(myfonts.f_wb)) {
-	    fp = get_font_name_props(screen->display, fnts[fBold].fs, &bold);
+	if (!check_fontname(new_fnames.f_wb)) {
+	    fp = get_font_name_props(screen->display, new_fnts[fBold].fs, &bold);
 	    if (fp != 0) {
-		myfonts.f_wb = widebold_font_name(fp);
+		new_fnames.f_wb = widebold_font_name(fp);
 		warn[fWBold] = fwAlways;
 		derived = True;
 	    }
 	}
 
-	if (check_fontname(myfonts.f_wb)) {
+	if (check_fontname(new_fnames.f_wb)) {
 
 	    xtermOpenFont(xw,
-			  myfonts.f_wb,
-			  &fnts[fWBold],
+			  new_fnames.f_wb,
+			  &new_fnts[fWBold],
 			  (screen->utf8_fonts
 			   ? warn[fWBold]
 			   : (fontWarningTypes) (xw->misc.fontWarnings + 1)),
+			  NULL,
 			  False);
 
 	    if (derived
-		&& !compatibleWideCounts(fnts[fWide].fs, fnts[fWBold].fs)) {
-		xtermCloseFont(xw, &fnts[fWBold]);
+		&& !compatibleWideCounts(new_fnts[fWide].fs, new_fnts[fWBold].fs)) {
+		xtermCloseFont(xw, &new_fnts[fWBold]);
 	    }
-	    if (fnts[fWBold].fs == 0) {
+	    if (new_fnts[fWBold].fs == 0) {
 		FREE_FNAME(f_wb);
-		if (IsEmpty(myfonts.f_w)) {
-		    myfonts.f_wb = x_strdup(myfonts.f_b);
+		if (IsEmpty(new_fnames.f_w)) {
+		    new_fnames.f_wb = x_strdup(new_fnames.f_b);
 		    warn[fWBold] = fwAlways;
-		    xtermCopyFontInfo(&fnts[fWBold], &fnts[fBold]);
+		    xtermCopyFontInfo(&new_fnts[fWBold], &new_fnts[fBold]);
 		    TRACE(("...cannot load wide-bold, use bold %s\n",
-			   NonNull(myfonts.f_b)));
+			   NonNull(new_fnames.f_b)));
 		} else {
-		    myfonts.f_wb = x_strdup(myfonts.f_w);
+		    new_fnames.f_wb = x_strdup(new_fnames.f_w);
 		    warn[fWBold] = fwAlways;
-		    xtermCopyFontInfo(&fnts[fWBold], &fnts[fWide]);
+		    xtermCopyFontInfo(&new_fnts[fWBold], &new_fnts[fWide]);
 		    TRACE(("...cannot load wide-bold, use wide %s\n",
-			   NonNull(myfonts.f_w)));
+			   NonNull(new_fnames.f_w)));
 		}
 	    } else {
 		TRACE(("...%s wide/bold %s\n",
 		       derived ? "derived" : "given",
-		       NonNull(myfonts.f_wb)));
-		cache_menu_font_name(screen, fontnum, fWBold, myfonts.f_wb);
+		       NonNull(new_fnames.f_wb)));
+		cache_menu_font_name(screen, fontnum, fWBold, new_fnames.f_wb);
 	    }
-	} else if (is_double_width_font(fnts[fBold].fs)) {
-	    xtermCopyFontInfo(&fnts[fWBold], &fnts[fBold]);
+	} else if (is_double_width_font(new_fnts[fBold].fs)) {
+	    xtermCopyFontInfo(&new_fnts[fWBold], &new_fnts[fBold]);
 	    warn[fWBold] = fwAlways;
-	    TRACE(("...bold font is double-width, use it %s\n", NonNull(myfonts.f_b)));
+	    TRACE(("...bold font is double-width, use it %s\n", NonNull(new_fnames.f_b)));
 	} else {
-	    xtermCopyFontInfo(&fnts[fWBold], &fnts[fWide]);
+	    xtermCopyFontInfo(&new_fnts[fWBold], &new_fnts[fWide]);
 	    warn[fWBold] = fwAlways;
-	    TRACE(("...cannot load wide bold font, use wide %s\n", NonNull(myfonts.f_w)));
+	    TRACE(("...cannot load wide bold font, use wide %s\n", NonNull(new_fnames.f_w)));
 	}
 
 	free(bold);
 
-	if (EmptyFont(fnts[fWBold].fs))
+	if (EmptyFont(new_fnts[fWBold].fs))
 	    goto bad;		/* can't use a 0-sized font */
     });
 
@@ -1233,26 +1254,26 @@ xtermLoadFont(XtermWidget xw,
      *
      * But if it did fail for some reason, then nevermind.
      */
-    if (EmptyFont(fnts[fBold].fs))
+    if (EmptyFont(new_fnts[fBold].fs))
 	goto bad;		/* can't use a 0-sized font */
 
-    if (!same_font_size(xw, fnts[fNorm].fs, fnts[fBold].fs)
-	&& (is_fixed_font(fnts[fNorm].fs) && is_fixed_font(fnts[fBold].fs))) {
+    if (!same_font_size(xw, new_fnts[fNorm].fs, new_fnts[fBold].fs)
+	&& (is_fixed_font(new_fnts[fNorm].fs) && is_fixed_font(new_fnts[fBold].fs))) {
 	TRACE(("...ignoring mismatched normal/bold fonts\n"));
-	xtermCloseFont(xw, &fnts[fBold]);
-	xtermCopyFontInfo(&fnts[fBold], &fnts[fNorm]);
+	xtermCloseFont(xw, &new_fnts[fBold]);
+	xtermCopyFontInfo(&new_fnts[fBold], &new_fnts[fNorm]);
     }
 
     if_OPT_WIDE_CHARS(screen, {
-	if (fnts[fWide].fs != 0
-	    && fnts[fWBold].fs != 0
-	    && (!comparable_metrics(fnts[fWide].fs, fnts[fWBold].fs)
-		|| (!same_font_size(xw, fnts[fWide].fs, fnts[fWBold].fs)
-		    && is_fixed_font(fnts[fWide].fs)
-		    && is_fixed_font(fnts[fWBold].fs)))) {
+	if (new_fnts[fWide].fs != 0
+	    && new_fnts[fWBold].fs != 0
+	    && (!comparable_metrics(new_fnts[fWide].fs, new_fnts[fWBold].fs)
+		|| (!same_font_size(xw, new_fnts[fWide].fs, new_fnts[fWBold].fs)
+		    && is_fixed_font(new_fnts[fWide].fs)
+		    && is_fixed_font(new_fnts[fWBold].fs)))) {
 	    TRACE(("...ignoring mismatched normal/bold wide fonts\n"));
-	    xtermCloseFont(xw, &fnts[fWBold]);
-	    xtermCopyFontInfo(&fnts[fWBold], &fnts[fWide]);
+	    xtermCloseFont(xw, &new_fnts[fWBold]);
+	    xtermCopyFontInfo(&new_fnts[fWBold], &new_fnts[fWide]);
 	}
     });
 
@@ -1260,28 +1281,28 @@ xtermLoadFont(XtermWidget xw,
      * Normal/bold fonts should be the same width.  Also, the min/max
      * values should be the same.
      */
-    if (!is_fixed_font(fnts[fNorm].fs)
-	|| !is_fixed_font(fnts[fBold].fs)
-	|| fnts[fNorm].fs->max_bounds.width != fnts[fBold].fs->max_bounds.width) {
+    if (!is_fixed_font(new_fnts[fNorm].fs)
+	|| !is_fixed_font(new_fnts[fBold].fs)
+	|| new_fnts[fNorm].fs->max_bounds.width != new_fnts[fBold].fs->max_bounds.width) {
 	TRACE(("Proportional font! normal %d/%d, bold %d/%d\n",
-	       fnts[fNorm].fs->min_bounds.width,
-	       fnts[fNorm].fs->max_bounds.width,
-	       fnts[fBold].fs->min_bounds.width,
-	       fnts[fBold].fs->max_bounds.width));
+	       new_fnts[fNorm].fs->min_bounds.width,
+	       new_fnts[fNorm].fs->max_bounds.width,
+	       new_fnts[fBold].fs->min_bounds.width,
+	       new_fnts[fBold].fs->max_bounds.width));
 	proportional = True;
     }
 
     if_OPT_WIDE_CHARS(screen, {
-	if (fnts[fWide].fs != 0
-	    && fnts[fWBold].fs != 0
-	    && (!is_fixed_font(fnts[fWide].fs)
-		|| !is_fixed_font(fnts[fWBold].fs)
-		|| fnts[fWide].fs->max_bounds.width != fnts[fWBold].fs->max_bounds.width)) {
+	if (new_fnts[fWide].fs != 0
+	    && new_fnts[fWBold].fs != 0
+	    && (!is_fixed_font(new_fnts[fWide].fs)
+		|| !is_fixed_font(new_fnts[fWBold].fs)
+		|| new_fnts[fWide].fs->max_bounds.width != new_fnts[fWBold].fs->max_bounds.width)) {
 	    TRACE(("Proportional font! wide %d/%d, wide bold %d/%d\n",
-		   fnts[fWide].fs->min_bounds.width,
-		   fnts[fWide].fs->max_bounds.width,
-		   fnts[fWBold].fs->min_bounds.width,
-		   fnts[fWBold].fs->max_bounds.width));
+		   new_fnts[fWide].fs->min_bounds.width,
+		   new_fnts[fWide].fs->max_bounds.width,
+		   new_fnts[fWBold].fs->min_bounds.width,
+		   new_fnts[fWBold].fs->max_bounds.width));
 	    proportional = True;
 	}
     });
@@ -1300,13 +1321,13 @@ xtermLoadFont(XtermWidget xw,
     screen->ifnts_ok = False;
 #endif
 
-    xtermCopyFontInfo(&(screen->fnts[fNorm]), &fnts[fNorm]);
-    xtermCopyFontInfo(&(screen->fnts[fBold]), &fnts[fBold]);
+    xtermCopyFontInfo(&(screen->fnts[fNorm]), &new_fnts[fNorm]);
+    xtermCopyFontInfo(&(screen->fnts[fBold]), &new_fnts[fBold]);
 #if OPT_WIDE_CHARS
-    xtermCopyFontInfo(&(screen->fnts[fWide]), &fnts[fWide]);
-    if (fnts[fWBold].fs == NULL)
-	xtermCopyFontInfo(&fnts[fWBold], &fnts[fWide]);
-    xtermCopyFontInfo(&(screen->fnts[fWBold]), &fnts[fWBold]);
+    xtermCopyFontInfo(&(screen->fnts[fWide]), &new_fnts[fWide]);
+    if (new_fnts[fWBold].fs == NULL)
+	xtermCopyFontInfo(&new_fnts[fWBold], &new_fnts[fWide]);
+    xtermCopyFontInfo(&(screen->fnts[fWBold]), &new_fnts[fWBold]);
 #endif
 
     xtermUpdateFontGCs(xw, screen->fnts);
@@ -1337,7 +1358,7 @@ xtermLoadFont(XtermWidget xw,
 	unsigned ch;
 
 #if OPT_TRACE
-#define TRACE_MISS(index) show_font_misses(#index, &fnts[index])
+#define TRACE_MISS(index) show_font_misses(#index, &new_fnts[index])
 	TRACE_MISS(fNorm);
 	TRACE_MISS(fBold);
 #if OPT_WIDE_CHARS
@@ -1355,12 +1376,12 @@ xtermLoadFont(XtermWidget xw,
 		    continue;
 	    }
 #endif
-	    if (IsXtermMissingChar(screen, n, &fnts[fNorm])) {
+	    if (IsXtermMissingChar(screen, n, &new_fnts[fNorm])) {
 		TRACE(("missing normal char #%d\n", n));
 		screen->fnt_boxes = False;
 		break;
 	    }
-	    if (IsXtermMissingChar(screen, n, &fnts[fBold])) {
+	    if (IsXtermMissingChar(screen, n, &new_fnts[fBold])) {
 		TRACE(("missing bold char #%d\n", n));
 		screen->fnt_boxes = False;
 		break;
@@ -1375,8 +1396,8 @@ xtermLoadFont(XtermWidget xw,
 	screen->enbolden = screen->bold_mode;
     } else {
 	screen->enbolden = screen->bold_mode
-	    && ((fnts[fNorm].fs == fnts[fBold].fs)
-		|| same_font_name(normal, myfonts.f_b));
+	    && ((new_fnts[fNorm].fs == new_fnts[fBold].fs)
+		|| same_font_name(normal, new_fnames.f_b));
     }
     TRACE(("Will %suse 1-pixel offset/overstrike to simulate bold\n",
 	   screen->enbolden ? "" : "not "));
@@ -1393,7 +1414,7 @@ xtermLoadFont(XtermWidget xw,
 			       True);
 	}
 #if OPT_SHIFT_FONTS
-	screen->menu_font_sizes[fontnum] = FontSize(fnts[fNorm].fs);
+	screen->menu_font_sizes[fontnum] = FontSize(new_fnts[fNorm].fs);
 #endif
     }
     if (normal)
@@ -1410,19 +1431,20 @@ xtermLoadFont(XtermWidget xw,
     FREE_FNAME(f_w);
     FREE_FNAME(f_wb);
 #endif
-    if (fnts[fNorm].fn == fnts[fBold].fn) {
-	free(fnts[fNorm].fn);
+    if (new_fnts[fNorm].fn == new_fnts[fBold].fn) {
+	free(new_fnts[fNorm].fn);
     } else {
-	free(fnts[fNorm].fn);
-	free(fnts[fBold].fn);
+	free(new_fnts[fNorm].fn);
+	free(new_fnts[fBold].fn);
     }
 #if OPT_WIDE_CHARS
-    free(fnts[fWide].fn);
-    free(fnts[fWBold].fn);
+    free(new_fnts[fWide].fn);
+    free(new_fnts[fWBold].fn);
 #endif
     return 1;
 
   bad:
+    recovered = False;
     if (normal)
 	free(normal);
     if (tmpname)
@@ -1435,30 +1457,31 @@ xtermLoadFont(XtermWidget xw,
 	SetItemSensitivity(fontMenuEntries[fontnum].widget, True);
 #endif
 	Bell(xw, XkbBI_MinorError, 0);
-	myfonts.f_n = screen->MenuFontName(old_fontnum);
-	return xtermLoadFont(xw, &myfonts, doresize, old_fontnum);
-    } else if (x_strcasecmp(myfonts.f_n, DEFFONT)) {
-	int code;
-
-	myfonts.f_n = DEFFONT;
-	TRACE(("...recovering for TrueType fonts\n"));
-	code = xtermLoadFont(xw, &myfonts, doresize, fontnum);
-	if (code) {
-	    SetItemSensitivity(fontMenuEntries[fontnum].widget,
+	new_fnames.f_n = screen->MenuFontName(old_fontnum);
+	if (xtermLoadFont(xw, &new_fnames, doresize, old_fontnum))
+		recovered = True;
+    } else if (x_strcasecmp(new_fnames.f_n, DEFFONT)
+	&& x_strcasecmp(new_fnames.f_n, old_fnts[fNorm].fn)) {
+	new_fnames.f_n = x_strdup(old_fnts[fNorm].fn);
+
+	TRACE(("...recovering from failed font-load\n"));
+	if (xtermLoadFont(xw, &new_fnames, doresize, fontnum)) {
+		recovered = True;
+	    	SetItemSensitivity(fontMenuEntries[fontnum].widget,
 			       UsingRenderFont(xw));
-	    TRACE(("...recovered size %dx%d\n",
+	    	TRACE(("...recovered size %dx%d\n",
 		   FontHeight(screen),
 		   FontWidth(screen)));
 	}
-	return code;
     }
 #endif
-
-    releaseWindowGCs(xw, win);
-
-    xtermCloseFonts(xw, fnts);
-    TRACE(("Fail Cgs - xtermLoadFont\n"));
-    return 0;
+    if (!recovered) {
+	releaseWindowGCs(xw, win);
+	xtermCloseFonts(xw, new_fnts);
+	TRACE(("Fail Cgs - xtermLoadFont\n"));
+	code = 0;
+    }
+    return code;
 }
 
 #if OPT_WIDE_ATTRS
@@ -1491,6 +1514,7 @@ xtermLoadItalics(XtermWidget xw)
 					 name,
 					 &(screen->ifnts[n]),
 					 fwResource,
+					 NULL,
 					 False);
 #if OPT_TRACE
 		    {
@@ -3064,6 +3088,7 @@ lookupOneFontSize(XtermWidget xw, int fo
 			  ((fontnum <= fontMenu_lastBuiltin)
 			   ? fwAlways
 			   : fwResource),
+			  NULL,
 			  True)) {
 	    if (fontnum <= fontMenu_lastBuiltin
 		|| strcmp(fnt.fn, DEFFONT)) {
@@ -3465,13 +3490,14 @@ HandleSetFont(Widget w GCC_UNUSED,
     }
 }
 
-void
+Bool
 SetVTFont(XtermWidget xw,
 	  int which,
 	  Bool doresize,
 	  const VTFontNames * fonts)
 {
     TScreen *screen = TScreenOf(xw);
+    Bool result = False;
 
     TRACE(("SetVTFont(which=%d, f_n=%s, f_b=%s)\n", which,
 	   (fonts && fonts->f_n) ? fonts->f_n : "<null>",
@@ -3480,33 +3506,31 @@ SetVTFont(XtermWidget xw,
     if (IsIcon(screen)) {
 	Bell(xw, XkbBI_MinorError, 0);
     } else if (which >= 0 && which < NMENUFONTS) {
-	VTFontNames myfonts;
+	VTFontNames new_fnames;
 
-	memset(&myfonts, 0, sizeof(myfonts));
+	memset(&new_fnames, 0, sizeof(new_fnames));
 	if (fonts != 0)
-	    myfonts = *fonts;
+	    new_fnames = *fonts;
 
 	if (which == fontMenu_fontsel) {	/* go get the selection */
-	    FindFontSelection(xw, myfonts.f_n, False);
+	    result = FindFontSelection(xw, new_fnames.f_n, False);
 	} else {
-	    int oldFont = screen->menu_font_number;
-
 #define USE_CACHED(field, name) \
-	    if (myfonts.field == 0) { \
-		myfonts.field = x_strdup(screen->menu_font_names[which][name]); \
-		TRACE(("set myfonts." #field " from menu_font_names[%d][" #name "] %s\n", \
-		       which, NonNull(myfonts.field))); \
+	    if (new_fnames.field == 0) { \
+		new_fnames.field = x_strdup(screen->menu_font_names[which][name]); \
+		TRACE(("set new_fnames." #field " from menu_font_names[%d][" #name "] %s\n", \
+		       which, NonNull(new_fnames.field))); \
 	    } else { \
-		TRACE(("set myfonts." #field " reused\n")); \
+		TRACE(("set new_fnames." #field " reused\n")); \
 	    }
 #define SAVE_FNAME(field, name) \
-	    if (myfonts.field != 0) { \
+	    if (new_fnames.field != 0) { \
 		if (screen->menu_font_names[which][name] == 0 \
-		 || strcmp(screen->menu_font_names[which][name], myfonts.field)) { \
+		 || strcmp(screen->menu_font_names[which][name], new_fnames.field)) { \
 		    TRACE(("updating menu_font_names[%d][" #name "] to %s\n", \
-			   which, myfonts.field)); \
+			   which, new_fnames.field)); \
 		    FREE_STRING(screen->menu_font_names[which][name]); \
-		    screen->menu_font_names[which][name] = x_strdup(myfonts.field); \
+		    screen->menu_font_names[which][name] = x_strdup(new_fnames.field); \
 		} \
 	    }
 
@@ -3517,7 +3541,7 @@ SetVTFont(XtermWidget xw,
 	    USE_CACHED(f_wb, fWBold);
 #endif
 	    if (xtermLoadFont(xw,
-			      &myfonts,
+			      &new_fnames,
 			      doresize, which)) {
 		/*
 		 * If successful, save the data so that a subsequent query via
@@ -3529,10 +3553,8 @@ SetVTFont(XtermWidget xw,
 		SAVE_FNAME(f_w, fWide);
 		SAVE_FNAME(f_wb, fWBold);
 #endif
+		result = TRUE;
 	    } else {
-		xtermLoadFont(xw,
-			      xtermFontName(screen->MenuFontName(oldFont)),
-			      doresize, oldFont);
 		Bell(xw, XkbBI_MinorError, 0);
 	    }
 	    FREE_FNAME(f_n);
@@ -3545,5 +3567,6 @@ SetVTFont(XtermWidget xw,
     } else {
 	Bell(xw, XkbBI_MinorError, 0);
     }
-    return;
+    TRACE(("...SetVTFont: %d\n", result));
+    return result;
 }
Index: xterm-308/fontutils.h
===================================================================
--- xterm-308.orig/fontutils.h
+++ xterm-308/fontutils.h
@@ -37,14 +37,14 @@
 /* *INDENT-OFF* */
 
 extern Bool xtermLoadDefaultFonts (XtermWidget /* xw */);
-extern Bool xtermOpenFont (XtermWidget /* xw */, const char */* name */, XTermFonts * /* result */, fontWarningTypes /* warn */, Bool /* force */);
+extern Bool xtermOpenFont (XtermWidget /* xw */, const char */* name */, XTermFonts * /* result */, fontWarningTypes /* warn */, XTermFonts * /* current */, Bool /* force */);
 extern XTermFonts * xtermCloseFont (XtermWidget /* xw */, XTermFonts * /* fnt */);
 extern const VTFontNames * xtermFontName (const char */* normal */);
 extern int lookupRelativeFontSize (XtermWidget /* xw */, int /* old */, int /* relative */);
 extern int xtermGetFont(const char * /* param */);
-extern int xtermLoadFont (XtermWidget /* xw */, const VTFontNames */* fonts */, Bool /* doresize */, int /* fontnum */);
+extern int xtermLoadFont (XtermWidget /* xw */, const VTFontNames */* fonts */, Bool /* doresizem*/, int /* fontnum */);
 extern void HandleSetFont PROTO_XT_ACTIONS_ARGS;
-extern void SetVTFont (XtermWidget /* xw */, int /* i */, Bool /* doresize */, const VTFontNames */* fonts */);
+extern Bool SetVTFont (XtermWidget /* xw */, int /* i */, Bool /* doresize */, const VTFontNames */* fonts */);
 extern void xtermCloseFonts (XtermWidget /* xw */, XTermFonts * /* fnts[fMAX] */);
 extern void xtermComputeFontInfo (XtermWidget /* xw */, VTwin */* win */, XFontStruct */* font */, int /* sbwidth */);
 extern void xtermCopyFontInfo (XTermFonts * /* target */, XTermFonts * /* source */);
Index: xterm-308/misc.c
===================================================================
--- xterm-308.orig/misc.c
+++ xterm-308/misc.c
@@ -5362,7 +5362,6 @@ xtermSetenv(const char *var, const char
 
 	    found = envindex;
 	    environ[found + 1] = NULL;
-	    environ = environ;
 	}
 
 	environ[found] = CastMallocN(char, 1 + len + strlen(value));
Index: xterm-308/xterm.h
===================================================================
--- xterm-308.orig/xterm.h
+++ xterm-308/xterm.h
@@ -868,7 +868,7 @@ extern void noleaks_cachedCgs (XtermWidg
 extern Bool CheckBufPtrs (TScreen * /* screen */);
 extern Bool set_cursor_gcs (XtermWidget /* xw */);
 extern int VTInit (XtermWidget /* xw */);
-extern void FindFontSelection (XtermWidget /* xw */, const char * /* atom_name */, Bool  /* justprobe */);
+extern Bool FindFontSelection (XtermWidget /* xw */, const char * /* atom_name */, Bool  /* justprobe */);
 extern void HideCursor (void);
 extern void RestartBlinking(TScreen * /* screen */);
 extern void ShowCursor (void);
openSUSE Build Service is sponsored by