542 lines
17 KiB
Diff
542 lines
17 KiB
Diff
|
From 4bf72cb8f1d3aa5f33c31eb817a5f0338f4aaf6f Mon Sep 17 00:00:00 2001
|
||
|
From: Ovidiu Panait <ovidiu.panait@windriver.com>
|
||
|
Date: Wed, 20 Sep 2017 05:02:00 +0000
|
||
|
Subject: [PATCH] Import upstream patch 20170826
|
||
|
|
||
|
20170826
|
||
|
+ fixes for "iterm2" (report by Leonardo Brondani Schenkel) -TD
|
||
|
+ corrected a warning from tic about keys which are the same, to skip
|
||
|
over missing/cancelled values.
|
||
|
+ add check in tic for unnecessary use of "2" to denote a shifted
|
||
|
special key.
|
||
|
+ improve checks in trim_sgr0, comp_parse.c and parse_entry.c, for
|
||
|
cancelled string capabilities.
|
||
|
+ add check in _nc_parse_entry() for invalid entry name, setting the
|
||
|
name to "invalid" to avoid problems storing entries.
|
||
|
+ add/improve checks in tic's parser to address invalid input
|
||
|
+ add a check in comp_scan.c to handle the special case where a
|
||
|
nontext file ending with a NUL rather than newline is given to tic
|
||
|
as input (Redhat #1484274).
|
||
|
+ allow for cancelled capabilities in _nc_save_str (Redhat #1484276).
|
||
|
+ add validity checks for "use=" target in _nc_parse_entry (Redhat
|
||
|
#1484284).
|
||
|
+ check for invalid strings in postprocess_termcap (Redhat #1484285)
|
||
|
+ reset secondary pointers on EOF in next_char() (Redhat #1484287).
|
||
|
+ guard _nc_safe_strcpy() and _nc_safe_strcat() against calls using
|
||
|
cancelled strings (Redhat #1484291).
|
||
|
+ correct typo in curs_memleaks.3x (Sven Joachim).
|
||
|
+ improve test/configure checks for some curses variants not based on
|
||
|
X/Open Curses.
|
||
|
+ add options for test/configure to disable checks for form, menu and
|
||
|
panel libraries.
|
||
|
|
||
|
Upstream-Status: Backport
|
||
|
CVE: CVE-2017-13732, CVE-2017-13734, CVE-2017-13730, CVE-2017-13729, CVE-2017-13728, CVE-2017-13731
|
||
|
|
||
|
|
||
|
Author: Sven Joachim <svenjoac@gmx.de>
|
||
|
Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com>
|
||
|
---
|
||
|
dist.mk | 4 +-
|
||
|
include/ncurses_defs | 4 +-
|
||
|
ncurses/tinfo/alloc_entry.c | 4 +-
|
||
|
ncurses/tinfo/comp_parse.c | 10 ++---
|
||
|
ncurses/tinfo/comp_scan.c | 6 ++-
|
||
|
ncurses/tinfo/parse_entry.c | 91 ++++++++++++++++++++++++++++++---------------
|
||
|
ncurses/tinfo/strings.c | 9 +++--
|
||
|
ncurses/tinfo/trim_sgr0.c | 4 +-
|
||
|
progs/tic.c | 75 ++++++++++++++++++++++++++++++++++++-
|
||
|
9 files changed, 157 insertions(+), 50 deletions(-)
|
||
|
|
||
|
diff --git a/dist.mk b/dist.mk
|
||
|
index 9af2699..2c70472 100644
|
||
|
--- a/dist.mk
|
||
|
+++ b/dist.mk
|
||
|
@@ -25,7 +25,7 @@
|
||
|
# use or other dealings in this Software without prior written #
|
||
|
# authorization. #
|
||
|
##############################################################################
|
||
|
-# $Id: dist.mk,v 1.1172 2017/07/13 00:15:27 tom Exp $
|
||
|
+# $Id: dist.mk,v 1.1179 2017/08/20 15:33:41 tom Exp $
|
||
|
# Makefile for creating ncurses distributions.
|
||
|
#
|
||
|
# This only needs to be used directly as a makefile by developers, but
|
||
|
@@ -37,7 +37,7 @@ SHELL = /bin/sh
|
||
|
# These define the major/minor/patch versions of ncurses.
|
||
|
NCURSES_MAJOR = 6
|
||
|
NCURSES_MINOR = 0
|
||
|
-NCURSES_PATCH = 20170715
|
||
|
+NCURSES_PATCH = 20170826
|
||
|
|
||
|
# We don't append the patch to the version, since this only applies to releases
|
||
|
VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR)
|
||
|
diff --git a/include/ncurses_defs b/include/ncurses_defs
|
||
|
index e6611b7..d237db1 100644
|
||
|
--- a/include/ncurses_defs
|
||
|
+++ b/include/ncurses_defs
|
||
|
@@ -1,4 +1,4 @@
|
||
|
-# $Id: ncurses_defs,v 1.73 2017/06/24 14:20:57 tom Exp $
|
||
|
+# $Id: ncurses_defs,v 1.75 2017/08/20 16:50:04 tom Exp $
|
||
|
##############################################################################
|
||
|
# Copyright (c) 2000-2016,2017 Free Software Foundation, Inc. #
|
||
|
# #
|
||
|
@@ -50,7 +50,9 @@ HAVE_BSD_STRING_H
|
||
|
HAVE_BTOWC
|
||
|
HAVE_BUILTIN_H
|
||
|
HAVE_CHGAT 1
|
||
|
+HAVE_COLOR_CONTENT 1
|
||
|
HAVE_COLOR_SET 1
|
||
|
+HAVE_CURSCR 1
|
||
|
HAVE_DIRENT_H
|
||
|
HAVE_ERRNO
|
||
|
HAVE_FCNTL_H
|
||
|
diff --git a/ncurses/tinfo/alloc_entry.c b/ncurses/tinfo/alloc_entry.c
|
||
|
index 5de09f1..09374d6 100644
|
||
|
--- a/ncurses/tinfo/alloc_entry.c
|
||
|
+++ b/ncurses/tinfo/alloc_entry.c
|
||
|
@@ -47,7 +47,7 @@
|
||
|
|
||
|
#include <tic.h>
|
||
|
|
||
|
-MODULE_ID("$Id: alloc_entry.c,v 1.60 2017/06/27 23:48:55 tom Exp $")
|
||
|
+MODULE_ID("$Id: alloc_entry.c,v 1.61 2017/08/25 09:09:08 tom Exp $")
|
||
|
|
||
|
#define ABSENT_OFFSET -1
|
||
|
#define CANCELLED_OFFSET -2
|
||
|
@@ -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;
|
||
|
|
||
|
diff --git a/ncurses/tinfo/comp_parse.c b/ncurses/tinfo/comp_parse.c
|
||
|
index 34e6216..580d4df 100644
|
||
|
--- a/ncurses/tinfo/comp_parse.c
|
||
|
+++ b/ncurses/tinfo/comp_parse.c
|
||
|
@@ -47,7 +47,7 @@
|
||
|
|
||
|
#include <tic.h>
|
||
|
|
||
|
-MODULE_ID("$Id: comp_parse.c,v 1.96 2017/04/15 15:36:58 tom Exp $")
|
||
|
+MODULE_ID("$Id: comp_parse.c,v 1.99 2017/08/26 16:15:50 tom Exp $")
|
||
|
|
||
|
static void sanity_check2(TERMTYPE2 *, bool);
|
||
|
NCURSES_IMPEXP void NCURSES_API(*_nc_check_termtype2) (TERMTYPE2 *, bool) = sanity_check2;
|
||
|
@@ -510,9 +510,9 @@ static void
|
||
|
fixup_acsc(TERMTYPE2 *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);
|
||
|
}
|
||
|
}
|
||
|
@@ -568,9 +568,7 @@ sanity_check2(TERMTYPE2 *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);
|
||
|
}
|
||
|
|
||
|
diff --git a/ncurses/tinfo/comp_scan.c b/ncurses/tinfo/comp_scan.c
|
||
|
index 40d7f6a..b207257 100644
|
||
|
--- a/ncurses/tinfo/comp_scan.c
|
||
|
+++ b/ncurses/tinfo/comp_scan.c
|
||
|
@@ -50,7 +50,7 @@
|
||
|
#include <ctype.h>
|
||
|
#include <tic.h>
|
||
|
|
||
|
-MODULE_ID("$Id: comp_scan.c,v 1.106 2017/04/22 11:41:12 tom Exp $")
|
||
|
+MODULE_ID("$Id: comp_scan.c,v 1.108 2017/08/25 22:57:21 tom Exp $")
|
||
|
|
||
|
/*
|
||
|
* Maximum length of string capability we'll accept before raising an error.
|
||
|
@@ -168,6 +168,8 @@ next_char(void)
|
||
|
if (result != 0) {
|
||
|
FreeAndNull(result);
|
||
|
FreeAndNull(pushname);
|
||
|
+ bufptr = 0;
|
||
|
+ bufstart = 0;
|
||
|
allocated = 0;
|
||
|
}
|
||
|
/*
|
||
|
@@ -222,6 +224,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;
|
||
|
diff --git a/ncurses/tinfo/parse_entry.c b/ncurses/tinfo/parse_entry.c
|
||
|
index 3fa2f25..bbbfcb2 100644
|
||
|
--- a/ncurses/tinfo/parse_entry.c
|
||
|
+++ b/ncurses/tinfo/parse_entry.c
|
||
|
@@ -47,7 +47,7 @@
|
||
|
#include <ctype.h>
|
||
|
#include <tic.h>
|
||
|
|
||
|
-MODULE_ID("$Id: parse_entry.c,v 1.86 2017/06/28 00:53:12 tom Exp $")
|
||
|
+MODULE_ID("$Id: parse_entry.c,v 1.91 2017/08/26 16:13:34 tom Exp $")
|
||
|
|
||
|
#ifdef LINT
|
||
|
static short const parametrized[] =
|
||
|
@@ -180,6 +180,20 @@ _nc_extend_names(ENTRY * entryp, char *name, int token_type)
|
||
|
}
|
||
|
#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(ENTRY * entryp, int literal, bool silent)
|
||
|
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(ENTRY * entryp, int literal, bool silent)
|
||
|
* 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(ENTRY * entryp, int literal, bool silent)
|
||
|
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 */
|
||
|
@@ -641,13 +672,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.
|
||
|
@@ -672,10 +696,10 @@ postprocess_termcap(TERMTYPE2 *tp, bool has_base)
|
||
|
|
||
|
/* 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)) {
|
||
|
@@ -790,7 +814,7 @@ postprocess_termcap(TERMTYPE2 *tp, bool has_base)
|
||
|
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 {
|
||
|
@@ -867,17 +891,22 @@ postprocess_termcap(TERMTYPE2 *tp, bool has_base)
|
||
|
* 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;
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
@@ -886,7 +915,7 @@ postprocess_termcap(TERMTYPE2 *tp, bool has_base)
|
||
|
* 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;
|
||
|
}
|
||
|
@@ -938,9 +967,9 @@ postprocess_termcap(TERMTYPE2 *tp, bool has_base)
|
||
|
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);
|
||
|
}
|
||
|
}
|
||
|
diff --git a/ncurses/tinfo/strings.c b/ncurses/tinfo/strings.c
|
||
|
index 393d8e7..10ec6c8 100644
|
||
|
--- a/ncurses/tinfo/strings.c
|
||
|
+++ b/ncurses/tinfo/strings.c
|
||
|
@@ -1,5 +1,5 @@
|
||
|
/****************************************************************************
|
||
|
- * Copyright (c) 2000-2007,2012 Free Software Foundation, Inc. *
|
||
|
+ * Copyright (c) 2000-2012,2017 Free Software Foundation, Inc. *
|
||
|
* *
|
||
|
* Permission is hereby granted, free of charge, to any person obtaining a *
|
||
|
* copy of this software and associated documentation files (the *
|
||
|
@@ -35,8 +35,9 @@
|
||
|
**/
|
||
|
|
||
|
#include <curses.priv.h>
|
||
|
+#include <tic.h>
|
||
|
|
||
|
-MODULE_ID("$Id: strings.c,v 1.8 2012/02/22 22:34:31 tom Exp $")
|
||
|
+MODULE_ID("$Id: strings.c,v 1.9 2017/08/26 13:16:11 tom Exp $")
|
||
|
|
||
|
/****************************************************************************
|
||
|
* Useful string functions (especially for mvcur)
|
||
|
@@ -105,7 +106,7 @@ _nc_str_copy(string_desc * dst, string_desc * src)
|
||
|
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 char *src)
|
||
|
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) {
|
||
|
diff --git a/ncurses/tinfo/trim_sgr0.c b/ncurses/tinfo/trim_sgr0.c
|
||
|
index 4cbcb65..4d92d15 100644
|
||
|
--- a/ncurses/tinfo/trim_sgr0.c
|
||
|
+++ b/ncurses/tinfo/trim_sgr0.c
|
||
|
@@ -36,7 +36,7 @@
|
||
|
|
||
|
#include <tic.h>
|
||
|
|
||
|
-MODULE_ID("$Id: trim_sgr0.c,v 1.16 2017/04/05 22:33:07 tom Exp $")
|
||
|
+MODULE_ID("$Id: trim_sgr0.c,v 1.17 2017/08/26 14:54:16 tom Exp $")
|
||
|
|
||
|
#undef CUR
|
||
|
#define CUR tp->
|
||
|
@@ -263,7 +263,7 @@ _nc_trim_sgr0(TERMTYPE2 *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 --git a/progs/tic.c b/progs/tic.c
|
||
|
index c5d78e5..6dd4678 100644
|
||
|
--- a/progs/tic.c
|
||
|
+++ b/progs/tic.c
|
||
|
@@ -48,7 +48,7 @@
|
||
|
#include <parametrized.h>
|
||
|
#include <transform.h>
|
||
|
|
||
|
-MODULE_ID("$Id: tic.c,v 1.233 2017/07/15 17:40:19 tom Exp $")
|
||
|
+MODULE_ID("$Id: tic.c,v 1.243 2017/08/26 20:56:55 tom Exp $")
|
||
|
|
||
|
#define STDIN_NAME "<stdin>"
|
||
|
|
||
|
@@ -62,6 +62,10 @@ static bool showsummary = FALSE;
|
||
|
static char **namelst = 0;
|
||
|
static const char *to_remove;
|
||
|
|
||
|
+#if NCURSES_XNAMES
|
||
|
+static bool using_extensions = FALSE;
|
||
|
+#endif
|
||
|
+
|
||
|
static void (*save_check_termtype) (TERMTYPE2 *, bool);
|
||
|
static void check_termtype(TERMTYPE2 *tt, bool);
|
||
|
|
||
|
@@ -850,6 +854,7 @@ main(int argc, char *argv[])
|
||
|
/* FALLTHRU */
|
||
|
case 'x':
|
||
|
use_extended_names(TRUE);
|
||
|
+ using_extensions = TRUE;
|
||
|
break;
|
||
|
#endif
|
||
|
default:
|
||
|
@@ -2405,10 +2410,17 @@ check_conflict(TERMTYPE2 *tp)
|
||
|
const char *a = given[j].value;
|
||
|
bool first = TRUE;
|
||
|
|
||
|
+ if (!VALID_STRING(a))
|
||
|
+ continue;
|
||
|
+
|
||
|
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;
|
||
|
@@ -2431,6 +2443,67 @@ check_conflict(TERMTYPE2 *tp)
|
||
|
if (!first)
|
||
|
fprintf(stderr, "\n");
|
||
|
}
|
||
|
+#if NCURSES_XNAMES
|
||
|
+ if (using_extensions) {
|
||
|
+ /* *INDENT-OFF* */
|
||
|
+ static struct {
|
||
|
+ const char *xcurses;
|
||
|
+ const char *shifted;
|
||
|
+ } table[] = {
|
||
|
+ { "kDC", NULL },
|
||
|
+ { "kDN", "kind" },
|
||
|
+ { "kEND", NULL },
|
||
|
+ { "kHOM", NULL },
|
||
|
+ { "kLFT", NULL },
|
||
|
+ { "kNXT", NULL },
|
||
|
+ { "kPRV", NULL },
|
||
|
+ { "kRIT", NULL },
|
||
|
+ { "kUP", "kri" },
|
||
|
+ { NULL, NULL },
|
||
|
+ };
|
||
|
+ /* *INDENT-ON* */
|
||
|
+
|
||
|
+ /*
|
||
|
+ * SVr4 curses defines the "xcurses" names listed above except for
|
||
|
+ * the special cases in the "shifted" column. When using these
|
||
|
+ * names for xterm's extensions, that was confusing, and resulted
|
||
|
+ * in adding extended capabilities with "2" (shift) suffix. This
|
||
|
+ * check warns about unnecessary use of extensions for this quirk.
|
||
|
+ */
|
||
|
+ for (j = 0; given[j].keycode; ++j) {
|
||
|
+ const char *find = given[j].name;
|
||
|
+ int value;
|
||
|
+ char ch;
|
||
|
+
|
||
|
+ if (!VALID_STRING(given[j].value))
|
||
|
+ continue;
|
||
|
+
|
||
|
+ for (k = 0; table[k].xcurses; ++k) {
|
||
|
+ const char *test = table[k].xcurses;
|
||
|
+ size_t size = strlen(test);
|
||
|
+
|
||
|
+ if (!strncmp(find, test, size) && strcmp(find, test)) {
|
||
|
+ switch (sscanf(find + size, "%d%c", &value, &ch)) {
|
||
|
+ case 1:
|
||
|
+ if (value == 2) {
|
||
|
+ _nc_warning("expected '%s' rather than '%s'",
|
||
|
+ (table[k].shifted
|
||
|
+ ? table[k].shifted
|
||
|
+ : test), find);
|
||
|
+ } else if (value < 2 || value > 15) {
|
||
|
+ _nc_warning("expected numeric 2..15 '%s'", find);
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ _nc_warning("expected numeric suffix for '%s'", find);
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+#endif
|
||
|
free(given);
|
||
|
free(check);
|
||
|
}
|
||
|
--
|
||
|
2.10.2
|
||
|
|