Based on e3cc539c23ceb1640395236248f0ab5a26397557 Mon Sep 17 00:00:00 2001
From: Ethan A Merritt <merritt@u.washington.edu>
Date: Mon, 19 Nov 2018 11:35:25 -0800
Subject: [PATCH] various overflow cases found by fuzzing

Credits:
    Tim Blazytko
    Cornelius Aschermann
    Sergej Schumilo
    Nils Bars

Bug 2088: term.c(strlen_tex)
Bug 2089: cairo.trm metapost.trm tgif.trm (arbitrarily long font name)
Bug 2092: cgm.trm overwrites trailing '\0' in default font name
	  also context.trm emf.trm
Bug 2094: also post.trm
Bug 2095: eepic.trm (EEPIC_put_text) ignore request to print empty string
---
 src/set.c         |    2 +-
 src/term.c        |    2 +-
 term/cairo.trm    |    2 +-
 term/cgm.trm      |    9 ++-------
 term/context.trm  |    4 ++--
 term/eepic.trm    |    3 +++
 term/emf.trm      |    4 ++--
 term/metapost.trm |    2 +-
 term/post.trm     |    2 +-
 term/tgif.trm     |    2 +-
 10 files changed, 15 insertions(+), 17 deletions(-)

--- src/set.c
+++ src/set.c	2018-11-28 12:01:20.849952417 +0000
@@ -1100,7 +1100,7 @@ set_clabel()
     c_token++;
     label_contours = TRUE;
     if ((new_format = try_to_get_string())) {
-	strncpy(contour_format, new_format, sizeof(contour_format));
+	safe_strncpy(contour_format, new_format, sizeof(contour_format));
 	free(new_format);
     }
 }
--- src/term.c
+++ src/term.c	2018-11-28 11:58:29.925085933 +0000
@@ -3006,7 +3006,7 @@ strlen_tex(const char *str)
 	switch (*s) {
 	case '[':
 		while (*s && *s != ']') s++;
-		s++;
+		if (*s) s++;
 		break;
 	case '\\':
 		s++;
--- term/cairo.trm
+++ term/cairo.trm	2018-11-28 11:58:29.925085933 +0000
@@ -278,7 +278,7 @@ TERM_PUBLIC void cairotrm_options()
 				cairo_params->fontsize = 0;
 			} else {
 				sep = strcspn(s,",");
-				if (sep > 0) {
+				if (0 < sep && sep < MAX_ID_LEN) {
 					strncpy(cairo_params->fontname, s, sep);
 					cairo_params->fontname[sep] = '\0';
 				}
--- term/cgm.trm
+++ term/cgm.trm	2018-11-28 11:58:29.925085933 +0000
@@ -479,7 +479,7 @@ CGM_options()
 			font_index = 1;
 		    } else
 			free(s);
-		    strncpy(cgm_font, cgm_font_data[font_index-1].name, sizeof(cgm_font));
+		    safe_strncpy(cgm_font, cgm_font_data[font_index-1].name, sizeof(cgm_font));
 
 		} else {
 		      /* the user is specifying the font size */
@@ -836,12 +836,7 @@ CGM_set_font(const char *font)
 
     {
       char *s = cgm_font_data[font_index-1].name;
-
-      len = strlen(s);
-      if (len > 31)
-	len = 31;
-      strncpy(cgm_font, s, len);
-      cgm_font[len] = NUL;
+      safe_strncpy(cgm_font, s, sizeof(cgm_font));
     }
 
     /* set font size */
--- term/context.trm
+++ term/context.trm	2018-11-28 11:58:29.925085933 +0000
@@ -589,7 +589,7 @@ CONTEXT_options()
 			if ((tmp_string = try_to_get_string()) && (tmp_string != NULL)) {
 				CONTEXT_fontstring_parse(tmp_string, tmp_font, MAX_ID_LEN+1, &tmp_fontsize);
 				/* copies font name to parameters */
-				strncpy(CONTEXT_params.font, tmp_font, sizeof(CONTEXT_params.font));
+				safe_strncpy(CONTEXT_params.font, tmp_font, sizeof(CONTEXT_params.font));
 				tmp_font[MAX_ID_LEN] = NUL;
 				free(tmp_string);
 				/* save font size:
@@ -1375,7 +1375,7 @@ CONTEXT_set_font(const char *font)
 
 	/* saves font name & family to CONTEXT_font */
 	CONTEXT_fontstring_parse((char *)font, CONTEXT_font, sizeof(CONTEXT_font), &CONTEXT_fontsize_explicit);
-	strncpy(CONTEXT_font_explicit, CONTEXT_font, sizeof(CONTEXT_font_explicit));
+	safe_strncpy(CONTEXT_font_explicit, CONTEXT_font, sizeof(CONTEXT_font_explicit));
 
 	/* valid fontsize has been provided */
 	if (CONTEXT_fontsize_explicit > 0.) { /* XXX: if valid */
--- term/eepic.trm
+++ term/eepic.trm	2018-11-28 11:58:29.925085933 +0000
@@ -375,6 +375,9 @@ EEPIC_put_text(unsigned int x, unsigned
 {
     int i, l;
 
+    if (*str == '\0')
+	return;
+
     EEPIC_endline();
 
     fprintf(gpoutfile, "\\put(%d,%d)", x, y);
--- term/emf.trm
+++ term/emf.trm	2018-11-28 11:58:29.925085933 +0000
@@ -790,7 +790,7 @@ EMF_options()
 		*comma = '\0';
 	    }
 	    if (*s)
-		strncpy(emf_defaultfontname, s, sizeof(emf_defaultfontname));
+		safe_strncpy(emf_defaultfontname, s, sizeof(emf_defaultfontname));
 	    free(s);
 	    if (isanumber(c_token)) {
 		emf_defaultfontsize = int_expression();
@@ -1806,7 +1806,7 @@ ENHemf_put_text(unsigned int x, unsigned
 
     /* set up the global variables needed by enhanced_recursion() */
     enhanced_fontscale = 1.0;
-    strncpy(enhanced_escape_format,"&#x%2.2x;",sizeof(enhanced_escape_format));
+    safe_strncpy(enhanced_escape_format,"&#x%2.2x;",sizeof(enhanced_escape_format));
 
     ENHemf_opened_string = FALSE;
     ENHemf_overprint = 0;
--- term/metapost.trm
+++ term/metapost.trm	2018-11-28 11:58:29.925085933 +0000
@@ -315,7 +315,7 @@ MP_options()
 	    char *s;
 	    if ((s = try_to_get_string())) {
 		int sep = strcspn(s,",");
-		if (sep > 0) {
+		if (0 < sep && sep < sizeof(MP_fontname)) {
 		    strncpy(MP_fontname, s, sizeof(MP_fontname));
 		    MP_fontname[sep] = '\0';
 		}
--- term/post.trm
+++ term/post.trm	2018-11-28 11:58:29.925085933 +0000
@@ -1138,7 +1138,7 @@ PS_options()
 	term->h_char = (unsigned int)(ps_fontsize*PS_SCF*5/10);
     else
 	term->h_char = (unsigned int)(ps_fontsize*PS_SCF*6/10);
-    sprintf(PS_default_font,"%s,%g",ps_params->font,ps_fontsize);
+    snprintf(PS_default_font, sizeof(PS_default_font)-1, "%s, %.2g", ps_params->font, ps_fontsize);
 
     if (ps_params->terminal == PSTERM_POSTSCRIPT) {
 	if (ps_params->first_fontfile) {
--- term/tgif.trm
+++ term/tgif.trm	2018-11-28 11:58:29.929085861 +0000
@@ -370,7 +370,7 @@ TGIF_options()
 		int sep = strcspn(s,",");
 		if (s[sep] == ',' && (1 == sscanf(&s[sep+1],"%lf",&fontsize)))
 		    uActFontSize =  (int)(fontsize+0.5);
-		if (sep > 0) {
+		if (0 < sep && sep < sizeof(sActFont)) {
 		    strncpy(sActFont, s, sizeof(sActFont));
 		    sActFont[sep] = NUL;
 		}
