X-Git-Url: http://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=progs%2Ftoe.c;h=92819c195d1f3a4dc2b14dac5a486e5415b8fac0;hp=d57a5fe49f48c1391357ff4248235bdc97d1fc15;hb=deb0d07e8eb4803b9e9653359eab17a30d04369d;hpb=4e793faf6575b2297482f77b2bc3d18105c0fc76 diff --git a/progs/toe.c b/progs/toe.c index d57a5fe4..92819c19 100644 --- a/progs/toe.c +++ b/progs/toe.c @@ -1,5 +1,6 @@ /**************************************************************************** - * Copyright (c) 1998-2012,2013 Free Software Foundation, Inc. * + * Copyright 2018-2020,2021 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 #endif -MODULE_ID("$Id: toe.c,v 1.72 2013/05/25 20:13:07 tom Exp $") +MODULE_ID("$Id: toe.c,v 1.86 2021/10/10 00:55:32 tom Exp $") #define isDotname(name) (!strcmp(name, ".") || !strcmp(name, "..")) @@ -63,7 +64,7 @@ static size_t len_termdata; /* allocated size of ptr_termdata[] */ #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 @@ ExitProgram(int code) } #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 @@ compare_termdata(const void *a, const void *b) 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 @@ show_termdata(int eargc, char **eargv) 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 @@ show_termdata(int eargc, char **eargv) * 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 @@ show_termdata(int eargc, char **eargv) } 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); } } } @@ -232,16 +243,18 @@ make_db_name(char *dst, const char *src, unsigned limit) static const char suffix[] = DBM_SUFFIX; bool result = FALSE; - unsigned lens = sizeof(suffix) - 1; - unsigned size = strlen(src); - unsigned need = lens + size; + size_t lens = sizeof(suffix) - 1; + size_t size = strlen(src); + size_t need = lens + size; if (need <= limit) { if (size >= lens && !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 @@ make_db_name(char *dst, const char *src, unsigned limit) 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 @@ term_description(TERMTYPE *tp) /* 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 @@ string_sum(const char *value) } 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 @@ checksum_of(TERMTYPE *tp) /* 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 @@ sorthook(int db_index, int db_limit, const char *term_name, TERMTYPE *tp) } #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; @@ -367,7 +400,7 @@ copy_entryname(DIRENT * src) static int typelist(int eargc, char *eargv[], - bool verbosity, + int verbosity, DescHook hook) /* apply a function to each entry in given terminfo directories */ { @@ -424,7 +457,7 @@ typelist(int eargc, char *eargv[], } while ((entry = readdir(entrydir)) != 0) { char *name_2; - TERMTYPE lterm; + TERMTYPE2 lterm; char *cn; int status; @@ -440,11 +473,8 @@ typelist(int eargc, char *eargv[], (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 @@ typelist(int eargc, char *eargv[], /* apply the selected hook function */ hook(i, eargc, cn, <erm); } - _nc_free_termtype(<erm); + _nc_free_termtype2(<erm); free(name_2); } closedir(entrydir); @@ -478,7 +508,7 @@ typelist(int eargc, char *eargv[], code = _nc_db_first(capdbp, &key, &data); while (code == 0) { - TERMTYPE lterm; + TERMTYPE2 lterm; int used; char *have; char *cn; @@ -489,7 +519,7 @@ typelist(int eargc, char *eargv[], cn = _nc_first_name(lterm.term_names); /* apply the selected hook function */ hook(i, eargc, cn, <erm); - _nc_free_termtype(<erm); + _nc_free_termtype2(<erm); } } code = _nc_db_next(capdbp, &key, &data); @@ -500,8 +530,8 @@ typelist(int eargc, char *eargv[], } } } -#endif -#endif +#endif /* USE_HASHED_DB */ +#endif /* NCURSES_USE_DATABASE */ #if NCURSES_USE_TERMCAP #if HAVE_BSD_CGETENT { @@ -515,11 +545,13 @@ typelist(int eargc, char *eargv[], 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,8 +566,10 @@ typelist(int eargc, char *eargv[], 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)) @@ -572,7 +606,6 @@ main(int argc, char *argv[]) bool invert_dependencies = FALSE; bool header = FALSE; char *report_file = 0; - unsigned i; int code; int this_opt, last_opt = '?'; unsigned v_opt = 0; @@ -660,11 +693,13 @@ main(int argc, char *argv[]) /* 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 @@ main(int argc, char *argv[]) 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); } @@ -721,14 +758,15 @@ main(int argc, char *argv[]) DBDIRS state; int offset; const char *path; - char **eargv = allocArgv(2); + char **eargv = allocArgv((size_t) 2); size_t count = 0; if (eargv == 0) 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);