ncurses 5.7 - patch 20091219
[ncurses.git] / ncurses / tinfo / write_entry.c
index 12172deefd86a706b612e915c4a5e31f0471ad8e..2552eea56df9bcfc5f93de186ff21887c2debf3e 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2008,2009 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            *
@@ -54,7 +54,7 @@
 #define TRACE_OUT(p)           /*nothing */
 #endif
 
-MODULE_ID("$Id: write_entry.c,v 1.71 2008/07/05 20:06:25 tom Exp $")
+MODULE_ID("$Id: write_entry.c,v 1.75 2009/12/05 21:25:01 tom Exp $")
 
 static int total_written;
 
@@ -137,10 +137,12 @@ make_db_path(char *dst, const char *src, unsigned limit)
        if (_nc_is_dir_path(dst)) {
            rc = -1;
        } else {
+           static const char suffix[] = DBM_SUFFIX;
            unsigned have = strlen(dst);
-           if (have > 3 && strcmp(dst + have - 3, DBM_SUFFIX)) {
-               if (have + 3 <= limit)
-                   strcat(dst, DBM_SUFFIX);
+           unsigned need = strlen(suffix);
+           if (have > need && strcmp(dst + have - need, suffix)) {
+               if (have + need <= limit)
+                   strcat(dst, suffix);
                else
                    rc = -1;
            }
@@ -171,7 +173,11 @@ make_db_root(const char *path)
        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 +281,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 +344,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++;
 
@@ -354,7 +364,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 +398,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 +420,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
@@ -464,18 +478,18 @@ fake_write(char *dst,
           unsigned want,
           unsigned size)
 {
-    int have = (limit - *offset);
+    unsigned have = (limit - *offset);
 
     want *= size;
     if (have > 0) {
-       if ((int) want > have)
+       if (want > have)
            want = have;
        memcpy(dst + *offset, src, want);
        *offset += 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)
@@ -483,14 +497,15 @@ fake_write(char *dst,
 #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)
 {
-    size_t nextfree = 0;
+    int nextfree = 0;
     unsigned i;
 
     for (i = 0; i < strmax; i++) {
@@ -499,8 +514,8 @@ 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]), (int) nextfree));
        }
@@ -532,8 +547,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 +560,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)
@@ -593,7 +608,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 +701,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,
+                                  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,
+                                   extcnt,
+                                   offsets + tp->ext_Strings);
        TRACE_OUT(("after extended capnames, nextfree=%d", nextfree));
        strmax = tp->ext_Strings + extcnt;