libncurses: Import https://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.5.tar.gz changes

Change-Id: I3433d30ca01359fd2e3623ede96b531f0b39cbfa
Signed-off-by: micky387 <mickaelsaibi@free.fr>
diff --git a/progs/toe.c b/progs/toe.c
index 0d299b4..ecbfd53 100644
--- a/progs/toe.c
+++ b/progs/toe.c
@@ -1,5 +1,6 @@
 /****************************************************************************
- * Copyright (c) 1998-2012,2013 Free Software Foundation, Inc.              *
+ * Copyright 2018-2022,2023 Thomas E. Dickey                                *
+ * Copyright 1998-2013,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            *
@@ -44,7 +45,7 @@
 #include <hashed_db.h>
 #endif
 
-MODULE_ID("$Id: toe.c,v 1.74 2013/12/15 01:08:28 tom Exp $")
+MODULE_ID("$Id: toe.c,v 1.89 2023/07/01 17:04:46 tom Exp $")
 
 #define isDotname(name) (!strcmp(name, ".") || !strcmp(name, ".."))
 
@@ -63,7 +64,7 @@
 
 #if NO_LEAKS
 #undef ExitProgram
-static void ExitProgram(int code) GCC_NORETURN;
+static GCC_NORETURN void ExitProgram(int code);
 static void
 ExitProgram(int code)
 {
@@ -72,7 +73,7 @@
 }
 #endif
 
-static void failed(const char *) GCC_NORETURN;
+static GCC_NORETURN void failed(const char *);
 
 static void
 failed(const char *msg)
@@ -126,12 +127,15 @@
 static void
 show_termdata(int eargc, char **eargv)
 {
-    int j, k;
-    size_t n;
-
     if (use_termdata) {
+	size_t n;
+
 	if (eargc > 1) {
+	    int j;
+
 	    for (j = 0; j < eargc; ++j) {
+		int k;
+
 		for (k = 0; k <= j; ++k) {
 		    printf("--");
 		}
@@ -142,14 +146,20 @@
 	if (use_termdata > 1)
 	    qsort(ptr_termdata, use_termdata, sizeof(TERMDATA), compare_termdata);
 	for (n = 0; n < use_termdata; ++n) {
+	    int nk = -1;
 
 	    /*
 	     * If there is more than one database, show how they differ.
 	     */
 	    if (eargc > 1) {
 		unsigned long check = 0;
-		k = 0;
+		int k = 0;
 		for (;;) {
+		    char mark = ((check == 0
+				  || (check != ptr_termdata[n].checksum))
+				 ? '*'
+				 : '+');
+
 		    for (; k < ptr_termdata[n].db_index; ++k) {
 			printf("--");
 		    }
@@ -159,11 +169,10 @@
 		     * from the first entry's checksum, print "*". Otherwise
 		     * it looks enough like a duplicate to print "+".
 		     */
-		    printf("%c-", ((check == 0
-				    || (check != ptr_termdata[n].checksum))
-				   ? '*'
-				   : '+'));
+		    printf("%c-", mark);
 		    check = ptr_termdata[n].checksum;
+		    if (mark == '*' && nk < 0)
+			nk = (int) n;
 
 		    ++k;
 		    if ((n + 1) >= use_termdata
@@ -178,10 +187,12 @@
 		}
 		printf(":\t");
 	    }
+	    if (nk < 0)
+		nk = (int) n;
 
 	    (void) printf("%-10s\t%s\n",
 			  ptr_termdata[n].term_name,
-			  ptr_termdata[n].description);
+			  ptr_termdata[nk].description);
 	}
     }
 }
@@ -241,7 +252,9 @@
 	    && !strcmp(src + size - lens, suffix)) {
 	    _nc_STRCPY(dst, src, PATH_MAX);
 	} else {
-	    _nc_SPRINTF(dst, _nc_SLIMIT(PATH_MAX) "%s%s", src, suffix);
+	    _nc_SPRINTF(dst, _nc_SLIMIT(PATH_MAX) "%.*s%s",
+			(int) (PATH_MAX - sizeof(suffix)),
+			src, suffix);
 	}
 	result = TRUE;
     }
@@ -252,10 +265,10 @@
 typedef void (DescHook) (int /* db_index */ ,
 			 int /* db_limit */ ,
 			 const char * /* term_name */ ,
-			 TERMTYPE * /* term */ );
+			 TERMTYPE2 * /* term */ );
 
 static const char *
-term_description(TERMTYPE *tp)
+term_description(TERMTYPE2 *tp)
 {
     const char *desc;
 
@@ -270,7 +283,7 @@
 
 /* display a description for the type */
 static void
-deschook(int db_index, int db_limit, const char *term_name, TERMTYPE *tp)
+deschook(int db_index, int db_limit, const char *term_name, TERMTYPE2 *tp)
 {
     (void) db_index;
     (void) db_limit;
@@ -294,7 +307,7 @@
 }
 
 static unsigned long
-checksum_of(TERMTYPE *tp)
+checksum_of(TERMTYPE2 *tp)
 {
     unsigned long result = string_sum(tp->term_names);
     unsigned i;
@@ -313,7 +326,7 @@
 
 /* collect data, to sort before display */
 static void
-sorthook(int db_index, int db_limit, const char *term_name, TERMTYPE *tp)
+sorthook(int db_index, int db_limit, const char *term_name, TERMTYPE2 *tp)
 {
     TERMDATA *data = new_termdata();
 
@@ -324,10 +337,30 @@
 }
 
 #if NCURSES_USE_TERMCAP
+/*
+ * Check if the buffer contents are printable ASCII, ensuring that we do not
+ * accidentally pick up incompatible binary content from a hashed database.
+ */
+static bool
+is_termcap(char *buffer)
+{
+    bool result = TRUE;
+    while (*buffer != '\0') {
+	int ch = UChar(*buffer++);
+	if (ch == '\t')
+	    continue;
+	if (ch < ' ' || ch > '~') {
+	    result = FALSE;
+	    break;
+	}
+    }
+    return result;
+}
+
 static void
 show_termcap(int db_index, int db_limit, char *buffer, DescHook hook)
 {
-    TERMTYPE data;
+    TERMTYPE2 data;
     char *next = strchr(buffer, ':');
     char *last;
     char *list = buffer;
@@ -424,7 +457,7 @@
 		}
 		while ((entry = readdir(entrydir)) != 0) {
 		    char *name_2;
-		    TERMTYPE lterm;
+		    TERMTYPE2 lterm;
 		    char *cn;
 		    int status;
 
@@ -440,11 +473,8 @@
 			(void) fprintf(stderr,
 				       "%s: couldn't open terminfo file %s.\n",
 				       _nc_progname, name_2);
-			free(cwd_buf);
 			free(name_2);
-			closedir(entrydir);
-			closedir(termdir);
-			return (EXIT_FAILURE);
+			continue;
 		    }
 
 		    /* only visit things once, by primary name */
@@ -453,7 +483,7 @@
 			/* apply the selected hook function */
 			hook(i, eargc, cn, &lterm);
 		    }
-		    _nc_free_termtype(&lterm);
+		    _nc_free_termtype2(&lterm);
 		    free(name_2);
 		}
 		closedir(entrydir);
@@ -478,7 +508,7 @@
 
 		    code = _nc_db_first(capdbp, &key, &data);
 		    while (code == 0) {
-			TERMTYPE lterm;
+			TERMTYPE2 lterm;
 			int used;
 			char *have;
 			char *cn;
@@ -489,7 +519,7 @@
 				cn = _nc_first_name(lterm.term_names);
 				/* apply the selected hook function */
 				hook(i, eargc, cn, &lterm);
-				_nc_free_termtype(&lterm);
+				_nc_free_termtype2(&lterm);
 			    }
 			}
 			code = _nc_db_next(capdbp, &key, &data);
@@ -500,8 +530,8 @@
 		}
 	    }
 	}
-#endif
-#endif
+#endif /* USE_HASHED_DB */
+#endif /* NCURSES_USE_DATABASE */
 #if NCURSES_USE_TERMCAP
 #if HAVE_BSD_CGETENT
 	{
@@ -515,11 +545,13 @@
 	    db_array[1] = 0;
 
 	    if (cgetfirst(&buffer, db_array) > 0) {
-		show_termcap(i, eargc, buffer, hook);
-		free(buffer);
-		while (cgetnext(&buffer, db_array) > 0) {
+		if (is_termcap(buffer)) {
 		    show_termcap(i, eargc, buffer, hook);
 		    free(buffer);
+		    while (cgetnext(&buffer, db_array) > 0) {
+			show_termcap(i, eargc, buffer, hook);
+			free(buffer);
+		    }
 		}
 		cgetclose();
 		continue;
@@ -534,11 +566,13 @@
 	    if (verbosity)
 		(void) printf("#\n#%s:\n#\n", eargv[i]);
 
-	    if ((fp = fopen(eargv[i], "r")) != 0) {
+	    if ((fp = safe_fopen(eargv[i], "r")) != 0) {
 		while (fgets(buffer, sizeof(buffer), fp) != 0) {
+		    if (!is_termcap(buffer))
+			break;
 		    if (*buffer == '#')
 			continue;
-		    if (isspace(*buffer))
+		    if (isspace(UChar(*buffer)))
 			continue;
 		    show_termcap(i, eargc, buffer, hook);
 		}
@@ -572,7 +606,6 @@
     bool invert_dependencies = FALSE;
     bool header = FALSE;
     char *report_file = 0;
-    unsigned i;
     int code;
     int this_opt, last_opt = '?';
     unsigned v_opt = 0;
@@ -625,7 +658,7 @@
 	    usage();
 	}
     }
-    set_trace_level(v_opt);
+    use_verbosity(v_opt);
 
     if (report_file != 0) {
 	if (freopen(report_file, "r", stdin) == 0) {
@@ -660,11 +693,13 @@
     /* maybe we want a reverse-dependency listing? */
     if (invert_dependencies) {
 	ENTRY *qp, *rp;
-	int matchcount;
 
 	for_entry_list(qp) {
-	    matchcount = 0;
+	    int matchcount = 0;
+
 	    for_entry_list(rp) {
+		unsigned i;
+
 		if (rp->nuses == 0)
 		    continue;
 
@@ -694,15 +729,17 @@
 	DBDIRS state;
 	int offset;
 	int pass;
-	const char *path;
 	char **eargv = 0;
 
 	code = EXIT_FAILURE;
 	for (pass = 0; pass < 2; ++pass) {
 	    size_t count = 0;
+	    const char *path;
 
 	    _nc_first_db(&state, &offset);
 	    while ((path = _nc_next_db(&state, &offset)) != 0) {
+		if (quick_prefix(path))
+		    continue;
 		if (pass) {
 		    eargv[count] = strmalloc(path);
 		}
@@ -728,7 +765,8 @@
 	    failed("eargv");
 	_nc_first_db(&state, &offset);
 	if ((path = _nc_next_db(&state, &offset)) != 0) {
-	    eargv[count++] = strmalloc(path);
+	    if (!quick_prefix(path))
+		eargv[count++] = strmalloc(path);
 	}
 
 	code = typelist((int) count, eargv, header, hook);