NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

lib/45370: termcap emulation tget{flag,num,str} want nul terminated string



>Number:         45370
>Category:       lib
>Synopsis:       termcap emulation tget{flag,num,str} want nul terminated string
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Sep 16 18:45:00 +0000 2011
>Originator:     Takehiko NOZAKI
>Release:        NetBSD  5.99.55
>Organization:
N/A
>Environment:
NetBSD  5.99.55 NetBSD 5.99.55 (XXX) #6: Mon Aug 29 06:35:08 JST 2011  
root@:/usr/obj.amd64/sys/arch/amd64/compile/XXX amd64
>Description:
termcap's function tget{flag,num,str} traditionaly declared as following 
prototype:

    int tgetflag(char id[2]);
    int tgetnum(char id[2]);
    char *tgetstr(char id[2], char **area);

(http://pubs.opengroup.org/onlinepubs/007908799/xcurses/tgetent.html)

so that, id string is not expected to be nul terminated.
if id's length more than 2, we have to cut it first 2byte, and ignore after 3.

our old termcap library(and also GNU ncurses) considering such case.

http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/lib/libterm/Attic/termcap.c?rev=1.55&content-type=text/plain

(snip)
char *
tgetstr(const char *id, char **area)
{
...
        char ids[3];

...
        /*
         * XXX
         * This is for all the boneheaded programs that relied on tgetstr
         * to look only at the first 2 characters of the string passed...
         */
        ids[0] = id[0];
        ids[1] = id[1];
        ids[2] = '\0';
(snip)
>How-To-Repeat:
see "boneheaded programs" traditioanl ex/vi's usage of tget{flag,str}:

http://ex-vi.cvs.sourceforge.net/viewvc/ex-vi/ex-vi/ex_tty.c?revision=1.4&view=markup

(snip)
void
zap(void)
{
        register char *namp;
        register bool **fp;
        register char ***sp;
        int flag;
        char *string;

#ifndef UCVISUAL
        namp = "ambsdadbeohcinmincnsosulxbxnxtxx";
#else
        namp = "ambsdadbeohchzinmincnsosulxbxnxtxx";
#endif
        fp = sflags;
        do {
                flag = tgetflag(namp);
                *(*fp++) = flag;
                namp += 2;
        } while (*namp);
        namp = 
"albcbtcdceclcmcrcsdcdldmdoedeik0k1k2k3k4k5k6k7k8k9hoicimipkdkekhklkrkskullndnlpcrcscsesfsosrtatetiupvbvsveALDLUPDOLERI";
        sp = sstrs;
        do {
                string = tgetstr(namp, &aoftspace);
                *(*sp++) = string;
                namp += 2;
        } while (*namp);
}
(snip)
>Fix:
Index: termcap.c
===================================================================
RCS file: /cvsroot/src/lib/libterminfo/termcap.c,v
retrieving revision 1.14
diff -u -r1.14 termcap.c
--- termcap.c   18 Mar 2011 10:42:54 -0000      1.14
+++ termcap.c   16 Sep 2011 18:04:23 -0000
@@ -74,17 +74,19 @@
 }

 int
-tgetflag(const char *id)
+tgetflag(const char *_id)
 {
        uint32_t ind;
        size_t i;
        TERMUSERDEF *ud;
+       char id[3];

        _DIAGASSERT(id != NULL);

        if (cur_term == NULL)
                return 0;


+       strlcpy(&id[0], _id, sizeof(id));
        ind = _t_flaghash((const unsigned char *)id, strlen(id));
        if (ind <= __arraycount(_ti_cap_flagids)) {
                if (strcmp(id, _ti_cap_flagids[ind].id) == 0)
@@ -99,18 +101,20 @@
 }

 int
-tgetnum(const char *id)
+tgetnum(const char *_id)
 {
        uint32_t ind;
        size_t i;
        TERMUSERDEF *ud;
        const TENTRY *te;
+       char id[3];

        _DIAGASSERT(id != NULL);

        if (cur_term == NULL)
                return -1;


+       strlcpy(&id[0], _id, sizeof(id));
        ind = _t_numhash((const unsigned char *)id, strlen(id));
        if (ind <= __arraycount(_ti_cap_numids)) {
                te = &_ti_cap_numids[ind];
@@ -132,12 +136,13 @@
 }

 char *
-tgetstr(const char *id, char **area)
+tgetstr(const char *_id, char **area)
 {
        uint32_t ind;
        size_t i;
        TERMUSERDEF *ud;
        const char *str;
+       char id[3];

        _DIAGASSERT(id != NULL);

@@ -145,6 +150,7 @@
                return NULL;

        str = NULL;
+       strlcpy(&id[0], _id, sizeof(id));
        ind = _t_strhash((const unsigned char *)id, strlen(id));
        if (ind <= __arraycount(_ti_cap_strids)) {
                if (strcmp(id, _ti_cap_strids[ind].id) == 0) {



Home | Main Index | Thread Index | Old Index