X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Ftinfo%2Fwrite_entry.c;h=b1daf1649e2086389b45c263538c68e4e3224d42;hp=05027e0021a2dbd83a7d866808ca5bf210acf2df;hb=29b24b6ba47681c8a26007492567c3daecb3defe;hpb=40df80d8d3f96c991f55569bce475e71cc38be12 diff --git a/ncurses/tinfo/write_entry.c b/ncurses/tinfo/write_entry.c index 05027e00..b1daf164 100644 --- a/ncurses/tinfo/write_entry.c +++ b/ncurses/tinfo/write_entry.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. * + * Copyright (c) 1998-2010,2011 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 * @@ -39,14 +39,7 @@ #include #include -#include - #include -#include - -#ifndef S_ISDIR -#define S_ISDIR(mode) ((mode & S_IFMT) == S_IFDIR) -#endif #if 1 #define TRACE_OUT(p) DEBUG(2, p) @@ -54,7 +47,7 @@ #define TRACE_OUT(p) /*nothing */ #endif -MODULE_ID("$Id: write_entry.c,v 1.70 2007/11/17 23:38:28 tom Exp $") +MODULE_ID("$Id: write_entry.c,v 1.82 2011/10/30 14:33:13 tom Exp $") static int total_written; @@ -77,7 +70,7 @@ write_file(char *filename, TERMTYPE *tp) DEBUG(1, ("Created %s", filename)); if (write_object(tp, buffer, &offset, limit) == ERR - || fwrite(buffer, sizeof(char), offset, fp) != offset) { + || fwrite(buffer, sizeof(char), (size_t) offset, fp) != offset) { _nc_syserr_abort("error writing %s/%s", _nc_tic_dir(0), filename); } @@ -116,7 +109,7 @@ check_writeable(int code) #endif /* !USE_HASHED_DB */ static int -make_db_path(char *dst, const char *src, unsigned limit) +make_db_path(char *dst, const char *src, size_t limit) { int rc = -1; const char *top = _nc_tic_dir(0); @@ -134,16 +127,17 @@ make_db_path(char *dst, const char *src, unsigned limit) } #if USE_HASHED_DB if (rc == 0) { - if (_nc_is_dir_path(dst)) { - rc = -1; - } else { - unsigned have = strlen(dst); - if (have > 3 && strcmp(dst + have - 3, DBM_SUFFIX)) { - if (have + 3 <= limit) - strcat(dst, DBM_SUFFIX); - else - rc = -1; + static const char suffix[] = DBM_SUFFIX; + size_t have = strlen(dst); + size_t need = strlen(suffix); + if (have > need && strcmp(dst + (int) (have - need), suffix)) { + if (have + need <= limit) { + strcat(dst, suffix); + } else { + rc = -1; } + } else if (_nc_is_dir_path(dst)) { + rc = -1; } } #endif @@ -163,15 +157,20 @@ make_db_root(const char *path) #if USE_HASHED_DB DB *capdbp; - if ((capdbp = _nc_db_open(fullpath, TRUE)) == NULL) + if ((capdbp = _nc_db_open(fullpath, TRUE)) == NULL) { rc = -1; - else if (_nc_db_close(capdbp) < 0) + } else if (_nc_db_close(capdbp) < 0) { rc = -1; + } #else struct stat statbuf; if ((rc = stat(path, &statbuf)) < 0) { - rc = mkdir(path, 0777); + rc = mkdir(path +#if !defined(__MINGW32__) + ,0777 +#endif + ); } else if (_nc_access(path, R_OK | W_OK | X_OK) < 0) { rc = -1; /* permission denied */ } else if (!(S_ISDIR(statbuf.st_mode))) { @@ -275,6 +274,9 @@ _nc_write_entry(TERMTYPE *const tp) char *first_name, *other_names; char *ptr; + assert(strlen(tp->term_names) != 0); + assert(strlen(tp->term_names) < sizeof(name_list)); + (void) strcpy(name_list, tp->term_names); DEBUG(7, ("Name list = '%s'", name_list)); @@ -335,6 +337,7 @@ _nc_write_entry(TERMTYPE *const tp) while (*other_names != '\0') { ptr = other_names++; + assert(ptr < buffer + sizeof(buffer) - 1); while (*other_names != '|' && *other_names != '\0') other_names++; @@ -346,7 +349,6 @@ _nc_write_entry(TERMTYPE *const tp) _nc_db_put(capdb, &key, &data); } - _nc_db_close(capdb); } } #else /* !USE_HASHED_DB */ @@ -354,7 +356,7 @@ _nc_write_entry(TERMTYPE *const tp) start_time = 0; } - if (strlen(first_name) > sizeof(filename) - 3) + if (strlen(first_name) >= sizeof(filename) - (2 + LEAF_LEN)) _nc_warning("terminal name too long."); sprintf(filename, LEAF_FMT "/%s", first_name[0], first_name); @@ -388,7 +390,7 @@ _nc_write_entry(TERMTYPE *const tp) if (*other_names != '\0') *(other_names++) = '\0'; - if (strlen(ptr) > sizeof(linkname) - 3) { + if (strlen(ptr) > sizeof(linkname) - (2 + LEAF_LEN)) { _nc_warning("terminal alias %s too long.", ptr); continue; } @@ -410,8 +412,12 @@ _nc_write_entry(TERMTYPE *const tp) { int code; #if USE_SYMLINKS - strcpy(symlinkname, "../"); - strncat(symlinkname, filename, sizeof(symlinkname) - 4); + if (first_name[0] == linkname[0]) + strncpy(symlinkname, first_name, sizeof(symlinkname) - 1); + else { + strcpy(symlinkname, "../"); + strncat(symlinkname, filename, sizeof(symlinkname) - 4); + } symlinkname[sizeof(symlinkname) - 1] = '\0'; #endif /* USE_SYMLINKS */ #if HAVE_REMOVE @@ -456,42 +462,43 @@ _nc_write_entry(TERMTYPE *const tp) #endif /* USE_HASHED_DB */ } -static unsigned +static size_t fake_write(char *dst, unsigned *offset, - unsigned limit, + size_t limit, char *src, - unsigned want, - unsigned size) + size_t want, + size_t size) { - int have = (limit - *offset); + size_t have = (limit - *offset); want *= size; if (have > 0) { - if ((int) want > have) + if (want > have) want = have; memcpy(dst + *offset, src, want); - *offset += want; + *offset += (unsigned) want; } else { want = 0; } - return (int) (want / size); + return (want / size); } -#define Write(buf, size, count) fake_write(buffer, offset, limit, (char *) buf, count, size) +#define Write(buf, size, count) fake_write(buffer, offset, (size_t) limit, (char *) buf, (size_t) count, (size_t) size) #undef LITTLE_ENDIAN /* BSD/OS defines this as a feature macro */ #define HI(x) ((x) / 256) #define LO(x) ((x) % 256) -#define LITTLE_ENDIAN(p, x) (p)[0] = LO(x), (p)[1] = HI(x) +#define LITTLE_ENDIAN(p, x) (p)[0] = (unsigned char)LO(x), \ + (p)[1] = (unsigned char)HI(x) #define WRITE_STRING(str) (Write(str, sizeof(char), strlen(str) + 1) == strlen(str) + 1) static int -compute_offsets(char **Strings, unsigned strmax, short *offsets) +compute_offsets(char **Strings, size_t strmax, short *offsets) { - size_t nextfree = 0; - unsigned i; + int nextfree = 0; + size_t i; for (i = 0; i < strmax; i++) { if (Strings[i] == ABSENT_STRING) { @@ -499,19 +506,19 @@ compute_offsets(char **Strings, unsigned strmax, short *offsets) } else if (Strings[i] == CANCELLED_STRING) { offsets[i] = -2; } else { - offsets[i] = nextfree; - nextfree += strlen(Strings[i]) + 1; + offsets[i] = (short) nextfree; + nextfree += (int) strlen(Strings[i]) + 1; TRACE_OUT(("put Strings[%d]=%s(%d)", (int) i, - _nc_visbuf(Strings[i]), nextfree)); + _nc_visbuf(Strings[i]), (int) nextfree)); } } return nextfree; } static void -convert_shorts(unsigned char *buf, short *Numbers, unsigned count) +convert_shorts(unsigned char *buf, short *Numbers, size_t count) { - unsigned i; + size_t i; for (i = 0; i < count; i++) { if (Numbers[i] == ABSENT_NUMERIC) { /* HI/LO won't work */ buf[2 * i] = buf[2 * i + 1] = 0377; @@ -520,7 +527,7 @@ convert_shorts(unsigned char *buf, short *Numbers, unsigned count) buf[2 * i + 1] = 0377; } else { LITTLE_ENDIAN(buf + 2 * i, Numbers[i]); - TRACE_OUT(("put Numbers[%d]=%d", i, Numbers[i])); + TRACE_OUT(("put Numbers[%u]=%d", (unsigned) i, Numbers[i])); } } } @@ -532,8 +539,8 @@ convert_shorts(unsigned char *buf, short *Numbers, unsigned count) static unsigned extended_Booleans(TERMTYPE *tp) { - unsigned short result = 0; - unsigned short i; + unsigned result = 0; + unsigned i; for (i = 0; i < tp->ext_Booleans; ++i) { if (tp->Booleans[BOOLCOUNT + i] == TRUE) @@ -545,8 +552,8 @@ extended_Booleans(TERMTYPE *tp) static unsigned extended_Numbers(TERMTYPE *tp) { - unsigned short result = 0; - unsigned short i; + unsigned result = 0; + unsigned i; for (i = 0; i < tp->ext_Numbers; ++i) { if (tp->Numbers[NUMCOUNT + i] != ABSENT_NUMERIC) @@ -563,7 +570,7 @@ extended_Strings(TERMTYPE *tp) for (i = 0; i < tp->ext_Strings; ++i) { if (tp->Strings[STRCOUNT + i] != ABSENT_STRING) - result = (i + 1); + result = (unsigned short) (i + 1); } return result; } @@ -593,7 +600,7 @@ write_object(TERMTYPE *tp, char *buffer, unsigned *offset, unsigned limit) size_t namelen, boolmax, nummax, strmax; char zero = '\0'; size_t i; - short nextfree; + int nextfree; short offsets[MAX_ENTRY_SIZE / 2]; unsigned char buf[MAX_ENTRY_SIZE]; unsigned last_bool = BOOLWRITE; @@ -686,14 +693,22 @@ write_object(TERMTYPE *tp, char *buffer, unsigned *offset, unsigned limit) #if NCURSES_XNAMES if (extended_object(tp)) { - unsigned extcnt = NUM_EXT_NAMES(tp); + unsigned extcnt = (unsigned) NUM_EXT_NAMES(tp); if (even_boundary(nextfree)) return (ERR); - nextfree = compute_offsets(tp->Strings + STRCOUNT, tp->ext_Strings, offsets); + nextfree = compute_offsets(tp->Strings + STRCOUNT, + (size_t) tp->ext_Strings, + offsets); TRACE_OUT(("after extended string capabilities, nextfree=%d", nextfree)); - nextfree += compute_offsets(tp->ext_Names, extcnt, offsets + tp->ext_Strings); + + if (tp->ext_Strings >= SIZEOF(offsets)) + return (ERR); + + nextfree += compute_offsets(tp->ext_Names, + (size_t) extcnt, + offsets + tp->ext_Strings); TRACE_OUT(("after extended capnames, nextfree=%d", nextfree)); strmax = tp->ext_Strings + extcnt; @@ -720,7 +735,7 @@ write_object(TERMTYPE *tp, char *buffer, unsigned *offset, unsigned limit) TRACE_OUT(("WRITE %d numbers @%d", tp->ext_Numbers, *offset)); if (tp->ext_Numbers) { - convert_shorts(buf, tp->Numbers + NUMCOUNT, tp->ext_Numbers); + convert_shorts(buf, tp->Numbers + NUMCOUNT, (size_t) tp->ext_Numbers); if (Write(buf, 2, tp->ext_Numbers) != tp->ext_Numbers) return (ERR); }