/****************************************************************************
- * Copyright (c) 1998-2017,2018 Free Software Foundation, Inc. *
+ * Copyright 2018-2022,2023 Thomas E. Dickey *
+ * Copyright 1998-2016,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 *
#include <tic.h>
-MODULE_ID("$Id: read_entry.c,v 1.147 2018/04/01 01:32:39 tom Exp $")
-
-#define TYPE_CALLOC(type,elts) typeCalloc(type, (unsigned)(elts))
+MODULE_ID("$Id: read_entry.c,v 1.165 2023/04/08 20:14:49 tom Exp $")
#define MyNumber(n) (short) LOW_MSB(n)
int i;
size_t j;
size_t size = SIZEOF_SHORT;
- unsigned char ch;
for (i = 0; i < count; i++) {
unsigned mask = 0xff;
+ unsigned char ch = 0;
Numbers[i] = 0;
for (j = 0; j < size; ++j) {
ch = UChar(*buf++);
{
int i;
char *p;
+ bool corrupt = FALSE;
for (i = 0; i < count; i++) {
if (IS_NEG1(buf + 2 * i)) {
} else if (MyNumber(buf + 2 * i) > size) {
Strings[i] = ABSENT_STRING;
} else {
- Strings[i] = (MyNumber(buf + 2 * i) + table);
- TR(TRACE_DATABASE, ("Strings[%d] = %s", i, _nc_visbuf(Strings[i])));
+ int nn = MyNumber(buf + 2 * i);
+ if (nn >= 0 && nn < size) {
+ Strings[i] = (nn + table);
+ TR(TRACE_DATABASE, ("Strings[%d] = %s", i,
+ _nc_visbuf(Strings[i])));
+ } else {
+ if (!corrupt) {
+ corrupt = TRUE;
+ TR(TRACE_DATABASE,
+ ("ignore out-of-range index %d to Strings[]", nn));
+ _nc_warning("corrupt data found in convert_strings");
+ }
+ Strings[i] = ABSENT_STRING;
+ }
}
/* make sure all strings are NUL terminated */
if (VALID_STRING(Strings[i])) {
- for (p = Strings[i]; p <= table + size; p++)
+ for (p = Strings[i]; p < table + size; p++)
if (*p == '\0')
break;
/* if there is no NUL, ignore the string */
- if (p > table + size)
+ if (p >= table + size)
Strings[i] = ABSENT_STRING;
}
}
{
unsigned i;
+ DEBUG(2, (T_CALLED("_nc_init_termtype(tp=%p)"), (void *) tp));
+
#if NCURSES_XNAMES
tp->num_Booleans = BOOLCOUNT;
tp->num_Numbers = NUMCOUNT;
for_each_string(i, tp)
tp->Strings[i] = ABSENT_STRING;
+
+ DEBUG(2, (T_RETURN("")));
}
#if NCURSES_USE_DATABASE
char buf[MAX_ENTRY_SIZE + 2];
char *string_table;
unsigned want, have;
- bool need_ints;
size_t (*convert_numbers) (char *, NCURSES_INT2 *, int);
int size_of_numbers;
int max_entry_size = MAX_ENTRY_SIZE;
returnDB(TGETENT_NO);
}
#if NCURSES_EXT_NUMBERS
- if ((need_ints = (LOW_MSB(buf) == MAGIC2))) {
+ if (LOW_MSB(buf) == MAGIC2) {
convert_numbers = convert_32bits;
size_of_numbers = SIZEOF_INT2;
} else {
size_of_numbers = SIZEOF_SHORT;
}
#else
- if ((need_ints = (LOW_MSB(buf) == MAGIC2))) {
+ if (LOW_MSB(buf) == MAGIC2) {
convert_numbers = convert_32bits;
size_of_numbers = SIZEOF_32BITS;
} else {
|| bool_count < 0
|| num_count < 0
|| str_count < 0
+ || bool_count > BOOLCOUNT
+ || num_count > NUMCOUNT
+ || str_count > STRCOUNT
|| str_size < 0) {
returnDB(TGETENT_NO);
}
offset = (int) (have - MAX_NAME_SIZE);
/* grab the booleans */
- if ((ptr->Booleans = TYPE_CALLOC(NCURSES_SBOOL,
- max(BOOLCOUNT, bool_count))) == 0
- || Read(ptr->Booleans, (unsigned) bool_count) < bool_count) {
+ TYPE_CALLOC(NCURSES_SBOOL, max(BOOLCOUNT, bool_count), ptr->Booleans);
+ if (Read(ptr->Booleans, (unsigned) bool_count) < bool_count) {
returnDB(TGETENT_NO);
}
even_boundary(name_size + bool_count);
/* grab the numbers */
- if (!(ptr->Numbers = TYPE_CALLOC(NCURSES_INT2, max(NUMCOUNT, num_count)))
- || !read_numbers(buf, num_count)) {
+ TYPE_CALLOC(NCURSES_INT2, max(NUMCOUNT, num_count), ptr->Numbers);
+ if (!read_numbers(buf, num_count)) {
returnDB(TGETENT_NO);
}
convert_numbers(buf, ptr->Numbers, num_count);
- if ((ptr->Strings = TYPE_CALLOC(char *, max(STRCOUNT, str_count))) == 0) {
- returnDB(TGETENT_NO);
- }
+ TYPE_CALLOC(char *, max(STRCOUNT, str_count), ptr->Strings);
if (str_count) {
/* grab the string offsets */
if (ext_str_count >= (max_entry_size / 2)) {
returnDB(TGETENT_NO);
}
- if ((ptr->ext_Names = TYPE_CALLOC(char *, need)) == 0) {
- returnDB(TGETENT_NO);
- }
+ TYPE_CALLOC(char *, need, ptr->ext_Names);
TR(TRACE_DATABASE,
("ext_NAMES starting @%d in extended_strings, first = %s",
base, _nc_visbuf(ptr->ext_str_table + base)));
int code;
if (_nc_access(filename, R_OK) < 0
- || (fp = fopen(filename, "rb")) == 0) {
+ || (fp = safe_fopen(filename, BIN_R)) == 0) {
TR(TRACE_DATABASE, ("cannot open terminfo %s (errno=%d)", filename, errno));
code = TGETENT_NO;
} else {
{
int result = 0;
int nibble;
- int ch;
for (nibble = 0; nibble < 2; ++nibble) {
+ int ch = UChar(**source);
result <<= 4;
- ch = UChar(**source);
*source += 1;
if (ch >= '0' && ch <= '9') {
ch -= '0';
char *base = target;
int result = 0;
- if (!strncmp(source, "b64:", 4)) {
+ if (!strncmp(source, "b64:", (size_t) 4)) {
source += 4;
while (*source != '\0') {
int bits[4];
}
}
}
- } else if (!strncmp(source, "hex:", 4)) {
+ } else if (!strncmp(source, "hex:", (size_t) 4)) {
source += 4;
while (*source != '\0') {
int ch = decode_hex(&source);
(T_CALLED("_nc_read_tic_entry(file=%p, path=%s, name=%s)"),
filename, path, name));
+ assert(TGETENT_YES == TRUE); /* simplify call for _nc_name_match */
+
if ((used = decode_quickdump(buffer, path)) != 0
&& (code = _nc_read_termtype(tp, buffer, used)) == TGETENT_YES
- && _nc_name_match(tp->term_names, name, "|")) {
+ && (code = _nc_name_match(tp->term_names, name, "|")) == TGETENT_YES) {
TR(TRACE_DATABASE, ("loaded quick-dump for %s", name));
+ /* shorten name shown by infocmp */
+ _nc_STRCPY(filename, "$TERMINFO", limit);
} else
#if USE_HASHED_DB
if (make_db_filename(filename, limit, path)
* looking for compiled (binary) terminfo data.
*
* cgetent uses a two-level lookup. On the first it uses the given
- * name to return a record containing only the aliases for an entry.
+ * name to return a record containing only the aliases for an entry.
* On the second (using that list of aliases as a key), it returns the
* content of the terminal description. We expect second lookup to
* return data beginning with the same set of aliases.
code = _nc_read_file_entry(filename, tp);
}
#if NCURSES_USE_TERMCAP
- else if (code != TGETENT_YES) {
+ if (code != TGETENT_YES) {
code = _nc_read_termcap_entry(name, tp);
_nc_SPRINTF(filename, _nc_SLIMIT(PATH_MAX)
"%.*s", PATH_MAX - 1, _nc_get_source());
#endif /* NCURSES_USE_DATABASE */
/*
- * Find and read the compiled entry for a given terminal type, if it exists.
+ * Find and read the compiled entry for a given terminal type, if it exists.
* We take pains here to make sure no combination of environment variables and
* terminal type name can be used to overrun the file buffer.
*/
{
int code = TGETENT_NO;
+ if (name == 0)
+ return _nc_read_entry2("", filename, tp);
+
_nc_SPRINTF(filename, _nc_SLIMIT(PATH_MAX)
"%.*s", PATH_MAX - 1, name);
#if NCURSES_EXT_NUMBERS
/*
- * This entrypoint is used by tack.
+ * This entrypoint is used by tack 1.07
*/
NCURSES_EXPORT(int)
_nc_read_entry(const char *const name, char *const filename, TERMTYPE *const tp)