On 2017-08-12 19:24 +0200, Sven Joachim wrote: > Control: tags -1 - moreinfo > > On 2017-07-15 12:54 +0200, Sven Joachim wrote: > >> On 2017-07-15 11:38 +0100, Adam D. Barratt wrote: >> >>> Control: tags -1 + confirmed >>> >>> On Sun, 2017-07-09 at 19:40 +0200, Sven Joachim wrote: >>>> The same problem as in #867814 for stretch and almost the same fix, >>>> except that one inapplicable hunk has been removed from the patch. >>> >>> Please go ahead. >> >> Same answer as in #867814, the fallout from #868266 needs to be sorted >> out first → no upload this weekend, defer for 8.10. > > Unfortunately the fixes from the 20170715 patchlevel were rather large > and not easily backportable to jessie, but finally openSUSE[1] has come > up with a patch that I have stolen. The output of "infocmp -C" slightly > differs from the one in currently in jessie, but I think there are no > functional differences. At least perldoc works fine.
As in #867814, I would like to fix the seven new CVEs 2017-137{28..34} as well. The two additional patches are the same as the ones for stretch (modulo line numbers, since I ran "quilt refresh"). Cheers, Sven
diff -Nru ncurses-5.9+20140913/debian/changelog ncurses-5.9+20140913/debian/changelog --- ncurses-5.9+20140913/debian/changelog 2014-09-17 19:00:57.000000000 +0200 +++ ncurses-5.9+20140913/debian/changelog 2017-09-06 17:11:59.000000000 +0200 @@ -1,3 +1,18 @@ +ncurses (5.9+20140913-1+deb8u1) jessie; urgency=medium + + * Cherry-pick upstream fixes from the 20170701 and 20170708 patchlevels + for various crash bugs in the tic library and the tic binary + (CVE-2017-10684, CVE-2017-10685, CVE-2017-11112, CVE-2017-11113). + * Apply termcap-format fix from openSUSE's ncurses-5.9-55.6.1 package, + repairing a regression from the above security fixes (see #868266). + * Cherry-pick upstream fixes from the 20170826 patchlevel for more + crash bugs in the tic library (CVE-2017-13728, CVE-2017-13729, + CVE-2017-13730, CVE-2017-13731, CVE-2017-13732, CVE-2017-13734). + * Cerry-pick upstream fixes from the 20170902 patchlevel to fix + another crash bug in the tic program (CVE-2017-13733). + + -- Sven Joachim <svenj...@gmx.de> Wed, 06 Sep 2017 17:11:59 +0200 + ncurses (5.9+20140913-1) unstable; urgency=low * New upstream patchlevel. diff -Nru ncurses-5.9+20140913/debian/patches/cve-2017-13733.diff ncurses-5.9+20140913/debian/patches/cve-2017-13733.diff --- ncurses-5.9+20140913/debian/patches/cve-2017-13733.diff 1970-01-01 01:00:00.000000000 +0100 +++ ncurses-5.9+20140913/debian/patches/cve-2017-13733.diff 2017-09-06 17:11:59.000000000 +0200 @@ -0,0 +1,91 @@ +Author: Sven Joachim <svenj...@gmx.de> +Description: Fix for CVE-2017-13733 in the tic program + Fix for CVE-2017-13733 cherry-picked from upstream patchlevel + 20170902. +Bug-Debian: https://bugs.debian.org/873746 +Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1484290 +Forwarded: not-needed +Last-Update: 2017-09-06 + +--- + progs/dump_entry.c | 19 ++++++++++--------- + progs/tput.c | 2 +- + 2 files changed, 11 insertions(+), 10 deletions(-) + +--- a/progs/dump_entry.c ++++ b/progs/dump_entry.c +@@ -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]) && +--- a/progs/tput.c ++++ b/progs/tput.c +@@ -261,7 +261,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; diff -Nru ncurses-5.9+20140913/debian/patches/cve-fixes.diff ncurses-5.9+20140913/debian/patches/cve-fixes.diff --- ncurses-5.9+20140913/debian/patches/cve-fixes.diff 1970-01-01 01:00:00.000000000 +0100 +++ ncurses-5.9+20140913/debian/patches/cve-fixes.diff 2017-09-06 17:11:59.000000000 +0200 @@ -0,0 +1,173 @@ +Author: Sven Joachim <svenj...@gmx.de> +Description: Fixes for four CVEs + Fixes for CVE 2017-10684, CVE-2017-10685, CVE-2017-11112, + CVE-2017-11113 cherry-picked from upstream patchlevels 20170701 and + 20170708. +Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1464684 +Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1464685 +Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1464686 +Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1464687 +Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1464691 +Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1464692 +Forwarded: not-needed +Last-Update: 2017-07-09 + +--- + ncurses/tinfo/alloc_entry.c | 6 +++++- + ncurses/tinfo/parse_entry.c | 22 ++++++++++++---------- + progs/dump_entry.c | 30 +++++++++++++++++++----------- + 3 files changed, 36 insertions(+), 22 deletions(-) + +--- a/ncurses/tinfo/alloc_entry.c ++++ b/ncurses/tinfo/alloc_entry.c +@@ -96,7 +96,11 @@ _nc_save_str(const char *const string) + { + char *result = 0; + size_t old_next_free = next_free; +- size_t len = strlen(string) + 1; ++ size_t len; ++ ++ if (string == 0) ++ return _nc_save_str(""); ++ len = strlen(string) + 1; + + if (len == 1 && next_free != 0) { + /* +--- a/ncurses/tinfo/parse_entry.c ++++ b/ncurses/tinfo/parse_entry.c +@@ -236,13 +236,14 @@ _nc_parse_entry(struct entry *entryp, in + * implemented it. Note that the resulting terminal type was never the + * 2-character name, but was instead the first alias after that. + */ ++#define ok_TC2(s) (isgraph(UChar(s)) && (s) != '|') + ptr = _nc_curr_token.tk_name; + if (_nc_syntax == SYN_TERMCAP + #if NCURSES_XNAMES + && !_nc_user_definable + #endif + ) { +- if (ptr[2] == '|') { ++ if (ok_TC2(ptr[0]) && ok_TC2(ptr[1]) && (ptr[2] == '|')) { + ptr += 3; + _nc_curr_token.tk_name[2] = '\0'; + } +@@ -284,9 +285,11 @@ _nc_parse_entry(struct entry *entryp, in + if (is_use || is_tc) { + entryp->uses[entryp->nuses].name = _nc_save_str(_nc_curr_token.tk_valstring); + entryp->uses[entryp->nuses].line = _nc_curr_line; +- entryp->nuses++; +- if (entryp->nuses > 1 && is_tc) { +- BAD_TC_USAGE ++ if (VALID_STRING(entryp->uses[entryp->nuses].name)) { ++ entryp->nuses++; ++ if (entryp->nuses > 1 && is_tc) { ++ BAD_TC_USAGE ++ } + } + } else { + /* normal token lookup */ +@@ -571,7 +574,7 @@ append_acs0(string_desc * dst, int code, + static void + append_acs(string_desc * dst, int code, char *src) + { +- if (src != 0 && strlen(src) == 1) { ++ if (VALID_STRING(src) && strlen(src) == 1) { + append_acs0(dst, code, *src); + } + } +@@ -829,15 +832,14 @@ postprocess_termcap(TERMTYPE *tp, bool h + } + + if (tp->Strings[to_ptr->nte_index]) { ++ const char *s = tp->Strings[from_ptr->nte_index]; ++ const char *t = tp->Strings[to_ptr->nte_index]; + /* There's no point in warning about it if it's the same + * string; that's just an inefficiency. + */ +- if (strcmp( +- tp->Strings[from_ptr->nte_index], +- tp->Strings[to_ptr->nte_index]) != 0) ++ if (VALID_STRING(s) && VALID_STRING(t) && strcmp(s, t) != 0) + _nc_warning("%s (%s) already has an explicit value %s, ignoring ko", +- ap->to, ap->from, +- _nc_visbuf(tp->Strings[to_ptr->nte_index])); ++ ap->to, ap->from, t); + continue; + } + +--- a/progs/dump_entry.c ++++ b/progs/dump_entry.c +@@ -609,9 +609,10 @@ fmt_entry(TERMTYPE *tterm, + PredIdx num_strings = 0; + bool outcount = 0; + +-#define WRAP_CONCAT \ +- wrap_concat(buffer); \ +- outcount = TRUE ++#define WRAP_CONCAT1(s) wrap_concat(s); outcount = TRUE ++#define WRAP_CONCAT2(a,b) wrap_concat(a); WRAP_CONCAT1(b) ++#define WRAP_CONCAT3(a,b,c) wrap_concat(a); WRAP_CONCAT2(b,c) ++#define WRAP_CONCAT WRAP_CONCAT1(buffer) + + len = 12; /* terminfo file-header */ + +@@ -802,13 +803,21 @@ fmt_entry(TERMTYPE *tterm, + _nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer)) + "%s=!!! %s WILL NOT CONVERT !!!", + name, srccap); ++ WRAP_CONCAT; + } else if (suppress_untranslatable) { + continue; + } else { + char *s = srccap, *d = buffer; +- _nc_SPRINTF(d, _nc_SLIMIT(sizeof(buffer)) "..%s=", name); +- d += strlen(d); ++ WRAP_CONCAT3("..", name, "="); + while ((*d = *s++) != 0) { ++ if ((d - buffer + 1) >= (int) sizeof(buffer)) { ++ fprintf(stderr, ++ "%s: value for %s is too long\n", ++ _nc_progname, ++ name); ++ *d = '\0'; ++ break; ++ } + if (*d == ':') { + *d++ = '\\'; + *d = ':'; +@@ -817,13 +826,12 @@ fmt_entry(TERMTYPE *tterm, + } + d++; + } ++ WRAP_CONCAT; + } + } else { +- _nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer)) +- "%s=%s", name, cv); ++ WRAP_CONCAT3(name, "=", cv); + } + len += (int) strlen(capability) + 1; +- WRAP_CONCAT; + } else { + char *src = _nc_tic_expand(capability, + outform == F_TERMINFO, numbers); +@@ -839,8 +847,7 @@ fmt_entry(TERMTYPE *tterm, + strcpy_DYN(&tmpbuf, src); + } + len += (int) strlen(capability) + 1; +- wrap_concat(tmpbuf.text); +- outcount = TRUE; ++ WRAP_CONCAT1(tmpbuf.text); + } + } + /* e.g., trimmed_sgr0 */ +@@ -1203,7 +1210,8 @@ dump_entry(TERMTYPE *tterm, + } + if (len > critlen) { + (void) fprintf(stderr, +- "warning: %s entry is %d bytes long\n", ++ "%s: %s entry is %d bytes long\n", ++ _nc_progname, + _nc_first_name(tterm->term_names), + len); + SHOW_WHY("# WARNING: this entry, %d bytes long, may core-dump %s libraries!\n", diff -Nru ncurses-5.9+20140913/debian/patches/more-cve-fixes.diff ncurses-5.9+20140913/debian/patches/more-cve-fixes.diff --- ncurses-5.9+20140913/debian/patches/more-cve-fixes.diff 1970-01-01 01:00:00.000000000 +0100 +++ ncurses-5.9+20140913/debian/patches/more-cve-fixes.diff 2017-09-06 17:11:59.000000000 +0200 @@ -0,0 +1,285 @@ +Author: Sven Joachim <svenj...@gmx.de> +Description: Fixes for six CVEs in the tic library + Fixes for CVE-2017-13728, CVE-2017-13729, CVE-2017-13730, + CVE-2017-13731, CVE-2017-13732 and CVE-2017-13734 cherry-picked from + upstream patchlevel 20170826. +Bug-Debian: https://bugs.debian.org/873723 +Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1484274 +Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1484276 +Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1484284 +Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1484285 +Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1484287 +Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1484291 +Forwarded: not-needed +Last-Update: 2017-09-06 + +--- + ncurses/tinfo/alloc_entry.c | 2 + ncurses/tinfo/comp_parse.c | 8 +-- + ncurses/tinfo/comp_scan.c | 4 + + ncurses/tinfo/parse_entry.c | 89 +++++++++++++++++++++++++++++--------------- + ncurses/tinfo/strings.c | 5 +- + ncurses/tinfo/trim_sgr0.c | 2 + 6 files changed, 71 insertions(+), 39 deletions(-) + +--- a/ncurses/tinfo/alloc_entry.c ++++ b/ncurses/tinfo/alloc_entry.c +@@ -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; + +--- a/ncurses/tinfo/comp_parse.c ++++ b/ncurses/tinfo/comp_parse.c +@@ -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); + } + } +@@ -578,9 +578,7 @@ sanity_check2(TERMTYPE *tp, bool literal + PAIRED(enter_xon_mode, exit_xon_mode); + PAIRED(enter_am_mode, exit_am_mode); + ANDMISSING(label_off, label_on); +-#ifdef remove_clock + PAIRED(display_clock, remove_clock); +-#endif + ANDMISSING(set_color_pair, initialize_pair); + } + +--- a/ncurses/tinfo/comp_scan.c ++++ b/ncurses/tinfo/comp_scan.c +@@ -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; +--- a/ncurses/tinfo/parse_entry.c ++++ b/ncurses/tinfo/parse_entry.c +@@ -180,6 +180,20 @@ _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 +225,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 +276,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 +303,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 +655,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 +679,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 +797,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 +871,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 +895,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 +947,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); + } + } +--- a/ncurses/tinfo/strings.c ++++ b/ncurses/tinfo/strings.c +@@ -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) { +--- a/ncurses/tinfo/trim_sgr0.c ++++ b/ncurses/tinfo/trim_sgr0.c +@@ -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); diff -Nru ncurses-5.9+20140913/debian/patches/series ncurses-5.9+20140913/debian/patches/series --- ncurses-5.9+20140913/debian/patches/series 2014-09-15 20:01:33.000000000 +0200 +++ ncurses-5.9+20140913/debian/patches/series 2017-09-06 16:49:32.000000000 +0200 @@ -1,3 +1,7 @@ 01-debian-no-ada-doc.diff 02-debian-backspace.diff 03-debian-ncursesconfig-omit-L.diff +cve-fixes.diff +termcap-fix.diff +more-cve-fixes.diff +cve-2017-13733.diff diff -Nru ncurses-5.9+20140913/debian/patches/termcap-fix.diff ncurses-5.9+20140913/debian/patches/termcap-fix.diff --- ncurses-5.9+20140913/debian/patches/termcap-fix.diff 1970-01-01 01:00:00.000000000 +0100 +++ ncurses-5.9+20140913/debian/patches/termcap-fix.diff 2017-09-06 17:11:59.000000000 +0200 @@ -0,0 +1,63 @@ +Author: Sven Joachim <svenj...@gmx.de> +Description: Apply termcap-format fix from openSUSE +Bug-Debian: https://bugs.debian.org/868266 +Forwarded: not-needed +Last-Update: 2017-08-12 + +--- + progs/dump_entry.c | 30 ++++++++++++++++++++++++++++-- + 1 file changed, 28 insertions(+), 2 deletions(-) + +--- a/progs/dump_entry.c ++++ b/progs/dump_entry.c +@@ -427,6 +427,22 @@ wrap_concat(const char *src) + column += (int) need; + } + ++static void ++wrap_termap(const char *a, const char *b, const char *c) ++{ ++ size_t need = strlen(a)+strlen(b)+strlen(c); ++ size_t want = strlen(separator)+need; ++ if (column > INDENT ++ && column + (int) want > width) { ++ force_wrap(); ++ } ++ strcpy_DYN(&outbuf, a); ++ strcpy_DYN(&outbuf, b); ++ strcpy_DYN(&outbuf, c); ++ strcpy_DYN(&outbuf, separator); ++ column += (int) need; ++} ++ + #define IGNORE_SEP_TRAIL(first,last,sep_trail) \ + if ((size_t)(last - first) > sizeof(sep_trail)-1 \ + && !strncmp(first, sep_trail, sizeof(sep_trail)-1)) \ +@@ -808,7 +824,12 @@ fmt_entry(TERMTYPE *tterm, + continue; + } else { + char *s = srccap, *d = buffer; +- WRAP_CONCAT3("..", name, "="); ++ if (infodump) { ++ WRAP_CONCAT3("..", name, "="); ++ } else { ++ wrap_termap("..", name, "="); ++ outcount = TRUE; ++ } + while ((*d = *s++) != 0) { + if ((d - buffer + 1) >= (int) sizeof(buffer)) { + fprintf(stderr, +@@ -829,7 +850,12 @@ fmt_entry(TERMTYPE *tterm, + WRAP_CONCAT; + } + } else { +- WRAP_CONCAT3(name, "=", cv); ++ if (infodump) { ++ WRAP_CONCAT3(name, "=", cv); ++ } else { ++ wrap_termap(name, "=", cv); ++ outcount = TRUE; ++ } + } + len += (int) strlen(capability) + 1; + } else {