File ncurses-5.9-bsc10561xxx.patch of Package ncurses.6136

For the bugs
  bsc#1056127 CVE-2017-13733
  bsc#1056128 CVE-2017-13732
  bsc#1056129 CVE-2017-13731
  bsc#1056131 CVE-2017-13730
  bsc#1056132 CVE-2017-13729
  bsc#1056136 CVE-2017-13728
   
---
 ncurses/tinfo/alloc_entry.c |    2 
 ncurses/tinfo/comp_parse.c  |    6 +-
 ncurses/tinfo/comp_scan.c   |    4 +
 ncurses/tinfo/parse_entry.c |   90 +++++++++++++++++++++++++++++---------------
 ncurses/tinfo/strings.c     |    5 +-
 ncurses/tinfo/trim_sgr0.c   |    2 
 progs/dump_entry.c          |   19 ++++-----
 progs/tic.c                 |    4 +
 progs/tput.c                |    2 
 9 files changed, 87 insertions(+), 47 deletions(-)

--- ncurses/tinfo/alloc_entry.c
+++ ncurses/tinfo/alloc_entry.c	2017-11-30 09:57:16.247619007 +0000
@@ -98,7 +98,7 @@ _nc_save_str(const char *const string)
     size_t old_next_free = next_free;
     size_t len;
 
-    if (string == 0)
+    if (!VALID_STRING(string))
 	return _nc_save_str("");
     len = strlen(string) + 1;
 
--- ncurses/tinfo/comp_parse.c
+++ ncurses/tinfo/comp_parse.c	2017-11-30 09:57:16.247619007 +0000
@@ -520,9 +520,9 @@ static void
 fixup_acsc(TERMTYPE *tp, int literal)
 {
     if (!literal) {
-	if (acs_chars == 0
-	    && enter_alt_charset_mode != 0
-	    && exit_alt_charset_mode != 0)
+	if (acs_chars == ABSENT_STRING
+	    && PRESENT(enter_alt_charset_mode)
+	    && PRESENT(exit_alt_charset_mode))
 	    acs_chars = strdup(VT_ACSC);
     }
 }
--- ncurses/tinfo/comp_scan.c
+++ ncurses/tinfo/comp_scan.c	2017-11-30 09:57:16.251618932 +0000
@@ -168,6 +168,8 @@ next_char(void)
 	if (result != 0) {
 	    FreeAndNull(result);
 	    FreeAndNull(pushname);
+	    bufptr = 0;
+	    bufstart = 0;
 	    allocated = 0;
 	}
 	/*
@@ -223,6 +225,8 @@ next_char(void)
 		}
 		if ((bufptr = bufstart) != 0) {
 		    used = strlen(bufptr);
+		    if (used == 0)
+			return (EOF);
 		    while (iswhite(*bufptr)) {
 			if (*bufptr == '\t') {
 			    _nc_curr_col = (_nc_curr_col | 7) + 1;
--- ncurses/tinfo/parse_entry.c
+++ ncurses/tinfo/parse_entry.c	2017-11-30 09:57:16.251618932 +0000
@@ -180,6 +180,21 @@ _nc_extend_names(ENTRY * entryp, char *n
 }
 #endif /* NCURSES_XNAMES */
 
+static bool
+valid_entryname(const char *name)
+{
+    bool result = TRUE;
+    int ch;
+    while ((ch = UChar(*name++)) != '\0') {
+	if (ch <= ' ' || ch > '~' || ch == '/') {
+	    result = FALSE;
+	    break;
+	}
+    }
+    return result;
+}
+
+
 /*
  *	int
  *	_nc_parse_entry(entry, literal, silent)
@@ -211,6 +226,7 @@ _nc_parse_entry(struct entry *entryp, in
     int token_type;
     struct name_table_entry const *entry_ptr;
     char *ptr, *base;
+    const char *name;
     bool bad_tc_usage = FALSE;
 
     token_type = _nc_get_token(silent);
@@ -261,7 +277,12 @@ _nc_parse_entry(struct entry *entryp, in
      * results in the terminal type getting prematurely set to correspond
      * to that of the next entry.
      */
-    _nc_set_type(_nc_first_name(entryp->tterm.term_names));
+    name = _nc_first_name(entryp->tterm.term_names);
+    if (!valid_entryname(name)) {
+	_nc_warning("invalid entry name \"%s\"", name);
+	name = "invalid";
+    }
+    _nc_set_type(name);
 
     /* check for overly-long names and aliases */
     for (base = entryp->tterm.term_names; (ptr = strchr(base, '|')) != 0;
@@ -283,13 +304,24 @@ _nc_parse_entry(struct entry *entryp, in
 	bool is_use = (strcmp(_nc_curr_token.tk_name, "use") == 0);
 	bool is_tc = !is_use && (strcmp(_nc_curr_token.tk_name, "tc") == 0);
 	if (is_use || is_tc) {
+	    if (!VALID_STRING(_nc_curr_token.tk_valstring)
+		|| _nc_curr_token.tk_valstring[0] == '\0') {
+		_nc_warning("missing name for use-clause");
+		continue;
+	    } else if (!valid_entryname(_nc_curr_token.tk_valstring)) {
+		_nc_warning("invalid name for use-clause \"%s\"",
+			    _nc_curr_token.tk_valstring);
+		continue;
+	    } else if (entryp->nuses >= MAX_USES) {
+		_nc_warning("too many use-clauses, ignored \"%s\"",
+			    _nc_curr_token.tk_valstring);
+		continue;
+	    }
 	    entryp->uses[entryp->nuses].name = _nc_save_str(_nc_curr_token.tk_valstring);
 	    entryp->uses[entryp->nuses].line = _nc_curr_line;
-	    if (VALID_STRING(entryp->uses[entryp->nuses].name)) {
-		entryp->nuses++;
-		if (entryp->nuses > 1 && is_tc) {
-		    BAD_TC_USAGE
-		}
+	    entryp->nuses++;
+	    if (entryp->nuses > 1 && is_tc) {
+		BAD_TC_USAGE
 	    }
 	} else {
 	    /* normal token lookup */
@@ -624,13 +656,6 @@ static const char C_BS[] = "\b";
 static const char C_HT[] = "\t";
 
 /*
- * Note that WANTED and PRESENT are not simple inverses!  If a capability
- * has been explicitly cancelled, it's not considered WANTED.
- */
-#define WANTED(s)	((s) == ABSENT_STRING)
-#define PRESENT(s)	(((s) != ABSENT_STRING) && ((s) != CANCELLED_STRING))
-
-/*
  * This bit of legerdemain turns all the terminfo variable names into
  * references to locations in the arrays Booleans, Numbers, and Strings ---
  * precisely what's needed.
@@ -655,10 +680,10 @@ postprocess_termcap(TERMTYPE *tp, bool h
 
     /* if there was a tc entry, assume we picked up defaults via that */
     if (!has_base) {
-	if (WANTED(init_3string) && termcap_init2)
+	if (WANTED(init_3string) && PRESENT(termcap_init2))
 	    init_3string = _nc_save_str(termcap_init2);
 
-	if (WANTED(reset_2string) && termcap_reset)
+	if (WANTED(reset_2string) && PRESENT(termcap_reset))
 	    reset_2string = _nc_save_str(termcap_reset);
 
 	if (WANTED(carriage_return)) {
@@ -773,7 +798,7 @@ postprocess_termcap(TERMTYPE *tp, bool h
 	if (init_tabs != 8 && init_tabs != ABSENT_NUMERIC)
 	    _nc_warning("hardware tabs with a width other than 8: %d", init_tabs);
 	else {
-	    if (tab && _nc_capcmp(tab, C_HT))
+	    if (PRESENT(tab) && _nc_capcmp(tab, C_HT))
 		_nc_warning("hardware tabs with a non-^I tab string %s",
 			    _nc_visbuf(tab));
 	    else {
@@ -847,17 +872,22 @@ postprocess_termcap(TERMTYPE *tp, bool h
 	     * The magic moment -- copy the mapped key string over,
 	     * stripping out padding.
 	     */
-	    for (dp = buf2, bp = tp->Strings[from_ptr->nte_index]; *bp; bp++) {
-		if (bp[0] == '$' && bp[1] == '<') {
-		    while (*bp && *bp != '>') {
-			++bp;
-		    }
-		} else
-		    *dp++ = *bp;
-	    }
-	    *dp = '\0';
+	    bp = tp->Strings[from_ptr->nte_index];
+	    if (VALID_STRING(bp)) {
+		for (dp = buf2; *bp; bp++) {
+		    if (bp[0] == '$' && bp[1] == '<') {
+			while (*bp && *bp != '>') {
+			    ++bp;
+			}
+		    } else
+			*dp++ = *bp;
+		}
+		*dp = '\0';
 
-	    tp->Strings[to_ptr->nte_index] = _nc_save_str(buf2);
+		tp->Strings[to_ptr->nte_index] = _nc_save_str(buf2);
+	    } else {
+		tp->Strings[to_ptr->nte_index] = bp;
+	    }
 	}
 
 	/*
@@ -866,7 +896,7 @@ postprocess_termcap(TERMTYPE *tp, bool h
 	 * got mapped to kich1 and im to kIC to avoid a collision.
 	 * If the description has im but not ic, hack kIC back to kich1.
 	 */
-	if (foundim && WANTED(key_ic) && key_sic) {
+	if (foundim && WANTED(key_ic) && PRESENT(key_sic)) {
 	    key_ic = key_sic;
 	    key_sic = ABSENT_STRING;
 	}
@@ -918,9 +948,9 @@ postprocess_termcap(TERMTYPE *tp, bool h
 	    acs_chars = _nc_save_str(buf2);
 	    _nc_warning("acsc string synthesized from XENIX capabilities");
 	}
-    } else if (acs_chars == 0
-	       && enter_alt_charset_mode != 0
-	       && exit_alt_charset_mode != 0) {
+    } else if (acs_chars == ABSENT_STRING
+	       && PRESENT(enter_alt_charset_mode)
+	       && PRESENT(exit_alt_charset_mode)) {
 	acs_chars = _nc_save_str(VT_ACSC);
     }
 }
--- ncurses/tinfo/strings.c
+++ ncurses/tinfo/strings.c	2017-11-30 09:57:16.251618932 +0000
@@ -35,6 +35,7 @@
 **/
 
 #include <curses.priv.h>
+#include <tic.h>
 
 MODULE_ID("$Id: strings.c,v 1.8 2012/02/22 22:34:31 tom Exp $")
 
@@ -105,7 +106,7 @@ _nc_str_copy(string_desc * dst, string_d
 NCURSES_EXPORT(bool)
 _nc_safe_strcat(string_desc * dst, const char *src)
 {
-    if (src != 0) {
+    if (PRESENT(src)) {
 	size_t len = strlen(src);
 
 	if (len < dst->s_size) {
@@ -126,7 +127,7 @@ _nc_safe_strcat(string_desc * dst, const
 NCURSES_EXPORT(bool)
 _nc_safe_strcpy(string_desc * dst, const char *src)
 {
-    if (src != 0) {
+    if (PRESENT(src)) {
 	size_t len = strlen(src);
 
 	if (len < dst->s_size) {
--- ncurses/tinfo/trim_sgr0.c
+++ ncurses/tinfo/trim_sgr0.c	2017-11-30 09:57:16.251618932 +0000
@@ -263,7 +263,7 @@ _nc_trim_sgr0(TERMTYPE *tp)
 	    /*
 	     * If rmacs is a substring of sgr(0), remove that chunk.
 	     */
-	    if (exit_alt_charset_mode != 0) {
+	    if (PRESENT(exit_alt_charset_mode)) {
 		TR(TRACE_DATABASE, ("scan for rmacs %s", _nc_visbuf(exit_alt_charset_mode)));
 		j = strlen(off);
 		k = strlen(exit_alt_charset_mode);
--- progs/dump_entry.c
+++ progs/dump_entry.c	2017-11-30 09:57:16.251618932 +0000
@@ -722,12 +722,12 @@ fmt_entry(TERMTYPE *tterm,
 #undef CUR
 #define CUR tterm->
     if (outform == F_TERMCAP) {
-	if (termcap_reset != ABSENT_STRING) {
-	    if (init_3string != ABSENT_STRING
+	if (VALID_STRING(termcap_reset)) {
+	    if (VALID_STRING(init_3string)
 		&& !strcmp(init_3string, termcap_reset))
 		DISCARD(init_3string);
 
-	    if (reset_2string != ABSENT_STRING
+	    if (VALID_STRING(reset_2string)
 		&& !strcmp(reset_2string, termcap_reset))
 		DISCARD(reset_2string);
 	}
@@ -799,7 +799,7 @@ fmt_entry(TERMTYPE *tterm,
 	buffer[0] = '\0';
 
 	if (predval != FAIL) {
-	    if (capability != ABSENT_STRING
+	    if (VALID_STRING(capability)
 		&& i + 1 > num_strings)
 		num_strings = i + 1;
 
@@ -877,8 +877,7 @@ fmt_entry(TERMTYPE *tterm,
 	    }
 	}
 	/* e.g., trimmed_sgr0 */
-	if (capability != ABSENT_STRING &&
-	    capability != CANCELLED_STRING &&
+	if (VALID_STRING(capability) &&
 	    capability != tterm->Strings[i])
 	    free(capability);
     }
@@ -1047,7 +1046,8 @@ kill_labels(TERMTYPE *tterm, int target)
 
     for (n = 0; n <= 10; ++n) {
 	_nc_SPRINTF(name, _nc_SLIMIT(sizeof(name)) "lf%d", n);
-	if ((cap = find_string(tterm, name)) != ABSENT_STRING
+	cap = find_string(tterm, name);
+	if (VALID_STRING(cap)
 	    && kill_string(tterm, cap)) {
 	    target -= (int) (strlen(cap) + 5);
 	    ++result;
@@ -1072,7 +1072,8 @@ kill_fkeys(TERMTYPE *tterm, int target)
 
     for (n = 60; n >= 0; --n) {
 	_nc_SPRINTF(name, _nc_SLIMIT(sizeof(name)) "kf%d", n);
-	if ((cap = find_string(tterm, name)) != ABSENT_STRING
+	cap = find_string(tterm, name);
+	if (VALID_STRING(cap)
 	    && kill_string(tterm, cap)) {
 	    target -= (int) (strlen(cap) + 5);
 	    ++result;
@@ -1094,7 +1095,7 @@ one_one_mapping(const char *mapping)
 {
     bool result = TRUE;
 
-    if (mapping != ABSENT_STRING) {
+    if (VALID_STRING(mapping)) {
 	int n = 0;
 	while (mapping[n] != '\0') {
 	    if (isLine(mapping[n]) &&
--- progs/tic.c
+++ progs/tic.c	2017-11-30 09:57:16.251618932 +0000
@@ -1963,8 +1963,12 @@ check_termtype(TERMTYPE *tp, bool litera
 
 	    for (k = j + 1; given[k].keycode; k++) {
 		const char *b = given[k].value;
+
+		if (!VALID_STRING(b))
+		    continue;
 		if (check[k])
 		    continue;
+
 		if (!_nc_capcmp(a, b)) {
 		    check[j] = 1;
 		    check[k] = 1;
--- progs/tput.c
+++ progs/tput.c	2017-11-30 09:58:23.430340881 +0000
@@ -300,7 +300,7 @@ tput(int argc, char *argv[])
 	}
 #endif
 	quit(4, "unknown terminfo capability '%s'", name);
-    } else if (s != ABSENT_STRING) {
+    } else if (VALID_STRING(s)) {
 	if (argc > 1) {
 	    int k;
 	    int ignored;
openSUSE Build Service is sponsored by